meta-messenger.js 0.0.1 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +660 -660
- package/README.md +174 -166
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
- package/scripts/build-go.mjs +36 -30
- package/scripts/detect-platform.mjs +41 -32
- package/scripts/download-prebuilt.mjs +126 -88
- package/scripts/package.mjs +11 -6
- package/scripts/postinstall.mjs +109 -73
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/native.ts","../src/types.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["/*\r\r\n * meta-messenger.js, Unofficial Meta Messenger Chat API for NodeJS\r\r\n * Copyright (c) 2026 Elysia and contributors\r\r\n */\r\n\r\nimport { EventEmitter } from \"node:events\";\r\n\r\nimport { native } from \"./native.js\";\r\nimport type {\r\n ClientEvent,\r\n ClientOptions,\r\n Cookies,\r\n CreateThreadResult,\r\n E2EEMessage,\r\n InitialData,\r\n Message,\r\n SearchUserResult,\r\n SendMessageOptions,\r\n SendMessageResult,\r\n UploadMediaResult,\r\n User,\r\n UserInfo,\r\n} from \"./types.js\";\r\n\r\ndeclare class TypedEventEmitter<T> {\r\n on<K extends keyof T>(event: K, listener: (...args: T[K] extends unknown[] ? T[K] : never) => void): this;\r\n once<K extends keyof T>(event: K, listener: (...args: T[K] extends unknown[] ? T[K] : never) => void): this;\r\n off<K extends keyof T>(event: K, listener: (...args: T[K] extends unknown[] ? T[K] : never) => void): this;\r\n emit<K extends keyof T>(event: K, ...args: T[K] extends unknown[] ? T[K] : never): boolean;\r\n removeAllListeners<K extends keyof T>(event?: K): this;\r\n}\r\n\r\nexport interface ClientEventMap {\r\n ready: [{ isNewSession: boolean }];\r\n fullyReady: [];\r\n reconnected: [];\r\n disconnected: [{ isE2EE?: boolean }];\r\n error: [Error];\r\n message: [Message];\r\n messageEdit: [{ messageId: string; threadId: number; newText: string; editCount?: number; timestampMs?: number }];\r\n messageUnsend: [{ messageId: string; threadId: number }];\r\n reaction: [{ messageId: string; threadId: number; actorId: number; reaction: string; timestampMs?: number }];\r\n typing: [{ threadId: number; senderId: number; isTyping: boolean }];\r\n readReceipt: [{ threadId: number; readerId: number; readWatermarkTimestampMs: number; timestampMs?: number }];\r\n e2eeConnected: [];\r\n e2eeMessage: [E2EEMessage];\r\n e2eeReaction: [{ messageId: string; chatJid: string; senderJid: string; senderId?: number; reaction: string }];\r\n e2eeReceipt: [{ type: string; chat: string; sender: string; messageIds: string[] }];\r\n deviceDataChanged: [{ deviceData: string }];\r\n}\r\n\r\n/**\r\n * Demonstrates how to use the Client class to connect to Messenger and handle messages (E2EE disabled for simplicity).\r\n *\r\n * @example\r\n * ```typescript\r\n * import { Client } from 'meta-messenger.js'\r\n *\r\n * const client = new Client({\r\n * c_user: 'your_user_id',\r\n * xs: 'your_xs_cookie',\r\n * datr: 'your_datr_cookie',\r\n * fr: 'your_fr_cookie'\r\n * })\r\n *\r\n * client.on('message', (message) => {\r\n * console.log('New message:', message)\r\n * if (message.text === 'ping') {\r\n * client.sendMessage(message.threadId, { text: 'pong' })\r\n * }\r\n * })\r\n *\r\n * await client.connect()\r\n * ```\r\n */\r\nexport class Client extends (EventEmitter as new () => TypedEventEmitter<ClientEventMap>) {\r\n private handle: number | null = null;\r\n private options: ClientOptions;\r\n private cookies: Cookies;\r\n private _user: User | null = null;\r\n private _initialData: InitialData | null = null;\r\n private eventLoopRunning = false;\r\n private eventLoopAbort: AbortController | null = null;\r\n private _socketReady = false;\r\n private _e2eeConnected = false;\r\n private _fullyReadyEmitted = false;\r\n private pendingEvents: ClientEvent[] = [];\r\n\r\n /**\r\n * Create a new Messenger client\r\n *\r\n * @param cookies - Authentication cookies\r\n * @param options - Client options\r\n */\r\n constructor(cookies: Cookies, options: ClientOptions = {}) {\r\n super();\r\n this.cookies = cookies;\r\n this.options = {\r\n // ! todo: detect platform automatically\r\n platform: \"facebook\",\r\n logLevel: \"none\",\r\n enableE2EE: true,\r\n autoReconnect: true,\r\n ...options,\r\n };\r\n }\r\n\r\n /**\r\n * Get the current user info\r\n */\r\n get user(): User | null {\r\n return this._user;\r\n }\r\n\r\n /**\r\n * Get the current user's Facebook ID\r\n */\r\n get currentUserId(): number | null {\r\n return this._user?.id ?? null;\r\n }\r\n\r\n /**\r\n * Get initial sync data (threads and messages)\r\n */\r\n get initialData(): InitialData | null {\r\n return this._initialData;\r\n }\r\n\r\n /**\r\n * Check if client is fully ready (socket ready + E2EE connected if enabled)\r\n */\r\n get isFullyReady(): boolean {\r\n if (!this._socketReady) return false;\r\n if (this.options.enableE2EE && !this._e2eeConnected) return false;\r\n return true;\r\n }\r\n\r\n /**\r\n * Check if client is connected\r\n */\r\n get isConnected(): boolean {\r\n if (!this.handle) return false;\r\n try {\r\n const status = native.isConnected(this.handle);\r\n return status.connected;\r\n }\n catch {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Check if E2EE is connected\r\n */\r\n get isE2EEConnected(): boolean {\r\n if (!this.handle) return false;\r\n try {\r\n const status = native.isConnected(this.handle);\r\n return status.e2eeConnected;\r\n }\n catch {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Connect to Messenger\r\n *\r\n * @returns User info and initial data\r\n */\r\n async connect(): Promise<{ user: User; initialData: InitialData }> {\r\n // Create native client\r\n const { handle } = native.newClient({\r\n cookies: this.cookies as Record<string, string>,\r\n platform: this.options.platform,\r\n devicePath: this.options.devicePath,\r\n deviceData: this.options.deviceData,\r\n logLevel: this.options.logLevel,\r\n });\r\n this.handle = handle;\r\n\r\n // Connect\r\n const result = native.connect(handle);\r\n this._user = result.user as User;\r\n this._initialData = result.initialData as InitialData;\r\n\r\n // Start event loop\r\n this.startEventLoop();\r\n\r\n // Connect E2EE if enabled\r\n if (this.options.enableE2EE) {\r\n this.connectE2EE().catch(err => {\r\n this.emit(\"error\", err);\r\n });\r\n }\r\n\r\n return {\r\n user: this._user,\r\n initialData: this._initialData,\r\n };\r\n }\r\n\r\n /**\r\n * Connect E2EE (end-to-end encryption)\r\n * @warn This Promise is not resolved after the connection setup is completed; instead, it is resolved after the function finishes executing.\\\r\n * You should not rely on this Promise to wait for the E2EE connection to be fully established.\r\n */\r\n async connectE2EE(): Promise<void> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n await native.connectE2EE(this.handle);\r\n }\r\n\r\n /**\r\n * Disconnect from Messenger\r\n */\r\n async disconnect(): Promise<void> {\r\n this.stopEventLoop();\r\n if (this.handle) {\r\n native.disconnect(this.handle);\r\n this.handle = null;\r\n }\r\n }\r\n\r\n /**\r\n * Send a text message\r\n *\r\n * @param threadId - Thread ID to send to\r\n * @param options - Message options (text, reply, mentions)\r\n * @returns Send result with message ID\r\n */\r\n async sendMessage(threadId: number, options: SendMessageOptions | string): Promise<SendMessageResult> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n\r\n const opts = typeof options === \"string\" ? { text: options } : options;\r\n\r\n return native.sendMessage(this.handle, {\r\n threadId,\r\n text: opts.text,\r\n replyToId: opts.replyToId,\r\n mentionIds: opts.mentions?.map(m => m.userId),\r\n mentionOffsets: opts.mentions?.map(m => m.offset),\r\n mentionLengths: opts.mentions?.map(m => m.length),\r\n });\r\n }\r\n\r\n /**\r\n * Send / Remove a reaction to a message\r\n *\r\n * @param threadId - Thread ID\r\n * @param messageId - Message ID to react to\r\n * @param emoji - Reaction emoji (to remove, simply omit this parameter)\r\n */\r\n async sendReaction(threadId: number, messageId: string, emoji?: string): Promise<void> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n await native.sendReaction(this.handle, threadId, messageId, emoji || \"\");\r\n }\r\n\r\n /**\r\n * Edit a message\r\n *\r\n * @param messageId - Message ID to edit\r\n * @param newText - New text content\r\n */\r\n async editMessage(messageId: string, newText: string): Promise<void> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n await native.editMessage(this.handle, messageId, newText);\r\n }\r\n\r\n /**\r\n * Unsend/delete a message\r\n *\r\n * @param messageId - Message ID to unsend\r\n */\r\n async unsendMessage(messageId: string): Promise<void> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n await native.unsendMessage(this.handle, messageId);\r\n }\r\n\r\n /**\r\n * Send typing indicator\r\n *\r\n * @param threadId - Thread ID\r\n * @param isTyping - Whether typing or not\r\n * @param isGroup - Whether it's a group chat\r\n */\r\n async sendTypingIndicator(threadId: number, isTyping: boolean = true, isGroup: boolean = false): Promise<void> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n await native.sendTyping(this.handle, threadId, isTyping, isGroup, isGroup ? 2 : 1);\r\n }\r\n\r\n /**\r\n * Mark messages as read\r\n *\r\n * @param threadId - Thread ID\r\n * @param watermarkTs - Timestamp to mark read up to (optional)\r\n */\r\n async markAsRead(threadId: number, watermarkTs?: number): Promise<void> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n await native.markRead(this.handle, threadId, watermarkTs);\r\n }\r\n\r\n /**\r\n * Upload media to Messenger\r\n *\r\n * @param threadId - Thread ID\r\n * @param data - File data as Buffer\r\n * @param filename - Filename\r\n * @param mimeType - MIME type\r\n * @param isVoice - Whether it's a voice message\r\n * @returns Upload result with Facebook ID\r\n */\r\n async uploadMedia(\r\n threadId: number,\r\n data: Buffer,\r\n filename: string,\r\n mimeType: string,\r\n isVoice: boolean = false,\r\n ): Promise<UploadMediaResult> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n return native.uploadMedia(this.handle, {\r\n threadId,\r\n filename,\r\n mimeType,\r\n data: Array.from(data),\r\n isVoice,\r\n });\r\n }\r\n\r\n /**\r\n * Send an image\r\n *\r\n * @param threadId - Thread ID\r\n * @param data - Image data as Buffer\r\n * @param filename - Filename\r\n * @param caption - Optional caption\r\n */\r\n async sendImage(threadId: number, data: Buffer, filename: string, caption?: string): Promise<SendMessageResult> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n return native.sendImage(this.handle, {\r\n threadId,\r\n data: Array.from(data),\r\n filename,\r\n caption,\r\n });\r\n }\r\n\r\n /**\r\n * Send a video\r\n *\r\n * @param threadId - Thread ID\r\n * @param data - Video data as Buffer\r\n * @param filename - Filename\r\n * @param caption - Optional caption\r\n */\r\n async sendVideo(threadId: number, data: Buffer, filename: string, caption?: string): Promise<SendMessageResult> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n return native.sendVideo(this.handle, {\r\n threadId,\r\n data: Array.from(data),\r\n filename,\r\n caption,\r\n });\r\n }\r\n\r\n /**\r\n * Send a voice message\r\n *\r\n * @param threadId - Thread ID\r\n * @param data - Audio data as Buffer\r\n * @param filename - Filename\r\n */\r\n async sendVoice(threadId: number, data: Buffer, filename: string): Promise<SendMessageResult> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n return native.sendVoice(this.handle, {\r\n threadId,\r\n data: Array.from(data),\r\n filename,\r\n });\r\n }\r\n\r\n /**\r\n * Send a file\r\n *\r\n * @param threadId - Thread ID\r\n * @param data - File data as Buffer\r\n * @param filename - Filename\r\n * @param mimeType - MIME type\r\n * @param caption - Optional caption\r\n */\r\n async sendFile(\r\n threadId: number,\r\n data: Buffer,\r\n filename: string,\r\n mimeType: string,\r\n caption?: string,\r\n ): Promise<SendMessageResult> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n return native.sendFile(this.handle, {\r\n threadId,\r\n data: Array.from(data),\r\n filename,\r\n mimeType,\r\n caption,\r\n });\r\n }\r\n\r\n /**\r\n * Send a sticker\r\n *\r\n * @param threadId - Thread ID\r\n * @param stickerId - Sticker ID\r\n */\r\n async sendSticker(threadId: number, stickerId: number): Promise<SendMessageResult> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n return native.sendSticker(this.handle, { threadId, stickerId });\r\n }\r\n\r\n /**\r\n * Create a 1:1 thread with a user\r\n *\r\n * @param userId - User ID to create thread with\r\n * @returns Created thread info\r\n */\r\n async createThread(userId: number): Promise<CreateThreadResult> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n return native.createThread(this.handle, { userId });\r\n }\r\n\r\n /**\r\n * Get detailed information about a user\r\n *\r\n * @param userId - User ID\r\n * @returns User info\r\n */\r\n async getUserInfo(userId: number): Promise<UserInfo> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n return native.getUserInfo(this.handle, { userId });\r\n }\r\n\r\n /**\r\n * Set group photo/avatar\r\n *\r\n * @param threadId - Thread ID\r\n * @param data - Image data as Buffer or base64 string\r\n * @param mimeType - MIME type (e.g., 'image/jpeg', 'image/png')\r\n *\r\n * @warn Cannot remove group photo. Messenger web doesn't have a remove option?\r\n */\r\n async setGroupPhoto(threadId: number, data: Buffer | string, mimeType: string = \"image/jpeg\"): Promise<void> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n const base64 = Buffer.isBuffer(data) ? data.toString(\"base64\") : data;\r\n await native.setGroupPhoto(this.handle, threadId, base64, mimeType);\r\n }\r\n\r\n /**\r\n * Rename a group thread\r\n *\r\n * @param threadId - Thread ID\r\n * @param newName - New name\r\n */\r\n async renameThread(threadId: number, newName: string): Promise<void> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n native.renameThread(this.handle, { threadId, newName });\r\n }\r\n\r\n /**\r\n * Mute a thread\r\n *\r\n * @param threadId - Thread ID\r\n * @param muteSeconds - Duration in seconds (-1 for forever, 0 to unmute)\r\n */\r\n async muteThread(threadId: number, muteSeconds: number = -1): Promise<void> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n native.muteThread(this.handle, { threadId, muteSeconds });\r\n }\r\n\r\n /**\r\n * Unmute a thread\r\n *\r\n * @param threadId - Thread ID\r\n */\r\n async unmuteThread(threadId: number): Promise<void> {\r\n return this.muteThread(threadId, 0);\r\n }\r\n\r\n /**\r\n * Delete a thread\r\n *\r\n * @param threadId - Thread ID\r\n */\r\n async deleteThread(threadId: number): Promise<void> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n native.deleteThread(this.handle, { threadId });\r\n }\r\n\r\n /**\r\n * Search for users\r\n *\r\n * @param query - Search query\r\n * @returns List of matching users\r\n */\r\n async searchUsers(query: string): Promise<SearchUserResult[]> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n const result = await native.searchUsers(this.handle, { query });\r\n return result.users;\r\n }\r\n\r\n // ========== E2EE Methods ==========\r\n\r\n /**\r\n * Send an E2EE message\r\n *\r\n * @param chatJid - Chat JID\r\n * @param text - Message text\r\n * @param options - Optional: replyToId and replyToSenderJid for replies\r\n */\r\n async sendE2EEMessage(\r\n chatJid: string,\r\n text: string,\r\n options?: { replyToId?: string; replyToSenderJid?: string },\r\n ): Promise<SendMessageResult> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n return native.sendE2EEMessage(this.handle, chatJid, text, options?.replyToId, options?.replyToSenderJid);\r\n }\r\n\r\n /**\r\n * Send / Remove an E2EE reaction\r\n *\r\n * @param chatJid - Chat JID\r\n * @param messageId - Message ID\r\n * @param senderJid - Sender JID\r\n * @param emoji - Reaction emoji (To remove it, simply omit this parameter)\r\n */\r\n async sendE2EEReaction(chatJid: string, messageId: string, senderJid: string, emoji?: string): Promise<void> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n await native.sendE2EEReaction(this.handle, chatJid, messageId, senderJid, emoji || \"\");\r\n }\r\n\r\n /**\r\n * Send E2EE typing indicator\r\n *\r\n * @param chatJid - Chat JID\r\n * @param isTyping - Whether typing\r\n */\r\n async sendE2EETyping(chatJid: string, isTyping: boolean = true): Promise<void> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n await native.sendE2EETyping(this.handle, chatJid, isTyping);\r\n }\r\n\r\n /**\r\n * Edit an E2EE message\r\n *\r\n * @param chatJid - Chat JID\r\n * @param messageId - Message ID to edit\r\n * @param newText - New message text\r\n */\r\n async editE2EEMessage(chatJid: string, messageId: string, newText: string): Promise<void> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n await native.editE2EEMessage(this.handle, chatJid, messageId, newText);\r\n }\r\n\r\n /**\r\n * Unsend/delete an E2EE message\r\n *\r\n * @param chatJid - Chat JID\r\n * @param messageId - Message ID to unsend\r\n */\r\n async unsendE2EEMessage(chatJid: string, messageId: string): Promise<void> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n await native.unsendE2EEMessage(this.handle, chatJid, messageId);\r\n }\r\n\r\n // ========== E2EE Media Methods ==========\r\n\r\n /**\r\n * Send an E2EE image\r\n *\r\n * @param chatJid - Chat JID\r\n * @param data - Image data as Buffer\r\n * @param mimeType - MIME type (e.g., image/jpeg, image/png)\r\n * @param options - Optional caption, dimensions, and reply options\r\n */\r\n async sendE2EEImage(\r\n chatJid: string,\r\n data: Buffer,\r\n mimeType: string = \"image/jpeg\",\r\n options?: { caption?: string; width?: number; height?: number; replyToId?: string; replyToSenderJid?: string },\r\n ): Promise<SendMessageResult> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n return native.sendE2EEImage(this.handle, {\r\n chatJid,\r\n data: Array.from(data),\r\n mimeType,\r\n caption: options?.caption,\r\n width: options?.width,\r\n height: options?.height,\r\n replyToId: options?.replyToId,\r\n replyToSenderJid: options?.replyToSenderJid,\r\n });\r\n }\r\n\r\n /**\r\n * Send an E2EE video\r\n *\r\n * @param chatJid - Chat JID\r\n * @param data - Video data as Buffer\r\n * @param mimeType - MIME type (default: video/mp4)\r\n * @param options - Optional caption, dimensions, duration, and reply options\r\n */\r\n async sendE2EEVideo(\r\n chatJid: string,\r\n data: Buffer,\r\n mimeType: string = \"video/mp4\",\r\n options?: {\r\n caption?: string;\r\n width?: number;\r\n height?: number;\r\n duration?: number;\r\n replyToId?: string;\r\n replyToSenderJid?: string;\r\n },\r\n ): Promise<SendMessageResult> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n return native.sendE2EEVideo(this.handle, {\r\n chatJid,\r\n data: Array.from(data),\r\n mimeType,\r\n caption: options?.caption,\r\n width: options?.width,\r\n height: options?.height,\r\n duration: options?.duration,\r\n replyToId: options?.replyToId,\r\n replyToSenderJid: options?.replyToSenderJid,\r\n });\r\n }\r\n\r\n /**\r\n * Send an E2EE audio/voice message\r\n *\r\n * @param chatJid - Chat JID\r\n * @param data - Audio data as Buffer\r\n * @param mimeType - MIME type (default: audio/ogg)\r\n * @param options - Optional PTT (push-to-talk/voice message), duration, and reply options\r\n */\r\n async sendE2EEAudio(\r\n chatJid: string,\r\n data: Buffer,\r\n mimeType: string = \"audio/ogg\",\r\n options?: { ptt?: boolean; duration?: number; replyToId?: string; replyToSenderJid?: string },\r\n ): Promise<SendMessageResult> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n return native.sendE2EEAudio(this.handle, {\r\n chatJid,\r\n data: Array.from(data),\r\n mimeType,\r\n ptt: options?.ptt ?? false,\r\n duration: options?.duration,\r\n replyToId: options?.replyToId,\r\n replyToSenderJid: options?.replyToSenderJid,\r\n });\r\n }\r\n\r\n /**\r\n * Send an E2EE document/file\r\n *\r\n * @param chatJid - Chat JID\r\n * @param data - File data as Buffer\r\n * @param filename - Filename\r\n * @param mimeType - MIME type\r\n * @param options - Optional reply options\r\n */\r\n async sendE2EEDocument(\r\n chatJid: string,\r\n data: Buffer,\r\n filename: string,\r\n mimeType: string,\r\n options?: { replyToId?: string; replyToSenderJid?: string },\r\n ): Promise<SendMessageResult> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n return native.sendE2EEDocument(this.handle, {\r\n chatJid,\r\n data: Array.from(data),\r\n filename,\r\n mimeType,\r\n replyToId: options?.replyToId,\r\n replyToSenderJid: options?.replyToSenderJid,\r\n });\r\n }\r\n\r\n /**\r\n * Send an E2EE sticker\r\n *\r\n * @param chatJid - Chat JID\r\n * @param data - Sticker data as Buffer (WebP format)\r\n * @param mimeType - MIME type (default: image/webp)\r\n * @param options - Optional reply options\r\n */\r\n async sendE2EESticker(\r\n chatJid: string,\r\n data: Buffer,\r\n mimeType: string = \"image/webp\",\r\n options?: { replyToId?: string; replyToSenderJid?: string },\r\n ): Promise<SendMessageResult> {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n return native.sendE2EESticker(this.handle, {\r\n chatJid,\r\n data: Array.from(data),\r\n mimeType,\r\n replyToId: options?.replyToId,\r\n replyToSenderJid: options?.replyToSenderJid,\r\n });\r\n }\r\n\r\n /**\r\n * Get E2EE device data as JSON string\r\n *\r\n * Use this to persist device data externally (e.g., in a database)\r\n *\r\n * @returns Device data as JSON string\r\n */\r\n getDeviceData(): string {\r\n if (!this.handle) throw new Error(\"Not connected\");\r\n const result = native.getDeviceData(this.handle);\r\n return result.deviceData;\r\n }\r\n\r\n private startEventLoop(): void {\r\n if (this.eventLoopRunning) return;\r\n this.eventLoopRunning = true;\r\n this.eventLoopAbort = new AbortController();\r\n\r\n const loop = async () => {\r\n while (this.eventLoopRunning && this.handle) {\r\n try {\r\n // Yield to event loop before polling to allow other operations\r\n await new Promise(resolve => setImmediate(resolve));\r\n\r\n const event = (await native.pollEvents(this.handle, 1000)) as ClientEvent;\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n if (!event || (event as any).type === \"timeout\") continue;\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n if ((event as any).type === \"closed\") {\r\n this.eventLoopRunning = false;\r\n break;\r\n }\r\n this.handleEvent(event);\r\n }\n catch (err) {\r\n if (this.eventLoopRunning) {\r\n this.emit(\"error\", err as Error);\r\n }\r\n }\r\n }\r\n };\r\n\r\n // background task\r\n setImmediate(loop).unref();\r\n }\r\n\r\n private stopEventLoop(): void {\r\n this.eventLoopRunning = false;\r\n this.eventLoopAbort?.abort();\r\n this.eventLoopAbort = null;\r\n }\r\n\r\n private checkFullyReady(): void {\r\n if (this.isFullyReady && !this._fullyReadyEmitted) {\r\n this._fullyReadyEmitted = true;\r\n this.emit(\"fullyReady\");\r\n // flush pending events\r\n const pending = this.pendingEvents;\r\n this.pendingEvents = [];\r\n for (const event of pending) {\r\n this.emitEvent(event);\r\n }\r\n }\r\n }\r\n\r\n private handleEvent(event: ClientEvent): void {\r\n switch (event.type) {\r\n // System events\r\n case \"ready\":\r\n this._socketReady = true;\r\n this.emit(\"ready\", event.data);\r\n this.checkFullyReady();\r\n break;\r\n case \"reconnected\":\r\n this.emit(\"reconnected\");\r\n break;\r\n case \"disconnected\":\r\n this._socketReady = false;\r\n this._e2eeConnected = false;\r\n this._fullyReadyEmitted = false;\r\n this.pendingEvents = [];\r\n this.emit(\"disconnected\", event.data || {});\r\n break;\r\n case \"error\":\r\n this.emit(\"error\", new Error(event.data.message));\r\n break;\r\n case \"e2eeConnected\":\r\n this._e2eeConnected = true;\r\n this.emit(\"e2eeConnected\");\r\n this.checkFullyReady();\r\n break;\r\n case \"deviceDataChanged\":\r\n this.emit(\"deviceDataChanged\", event.data);\r\n break;\r\n\r\n // queue until fullyReady\r\n case \"message\":\r\n case \"messageEdit\":\r\n case \"messageUnsend\":\r\n case \"reaction\":\r\n case \"typing\":\r\n case \"readReceipt\":\r\n case \"e2eeMessage\":\r\n case \"e2eeReaction\":\r\n case \"e2eeReceipt\":\r\n if (this._fullyReadyEmitted) {\r\n this.emitEvent(event);\r\n }\n else {\r\n this.pendingEvents.push(event);\r\n }\r\n break;\r\n }\r\n }\r\n\r\n private emitEvent(event: ClientEvent): void {\r\n switch (event.type) {\r\n case \"message\":\r\n this.emit(\"message\", event.data);\r\n break;\r\n case \"messageEdit\":\r\n this.emit(\"messageEdit\", event.data);\r\n break;\r\n case \"messageUnsend\":\r\n this.emit(\"messageUnsend\", event.data);\r\n break;\r\n case \"reaction\":\r\n this.emit(\"reaction\", event.data);\r\n break;\r\n case \"typing\":\r\n this.emit(\"typing\", event.data);\r\n break;\r\n case \"readReceipt\":\r\n this.emit(\"readReceipt\", event.data);\r\n break;\r\n case \"e2eeMessage\":\r\n this.emit(\"e2eeMessage\", event.data);\r\n break;\r\n case \"e2eeReaction\":\r\n this.emit(\"e2eeReaction\", event.data);\r\n break;\r\n case \"e2eeReceipt\":\r\n this.emit(\"e2eeReceipt\", event.data);\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Unload the native library (for cleanup)\r\n * @warn Any attempt to find or call a function from this library after unloading it will crash.\r\n * @returns void\r\n */\r\n public unloadLibrary(): void {\r\n if (this.handle) {\r\n native.unload();\r\n }\r\n }\r\n}\r\n","/*\r\r\n * meta-messenger.js, Unofficial Meta Messenger Chat API for NodeJS\r\r\n * Copyright (c) 2026 Elysia and contributors\r\r\n */\r\n\r\nimport fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport { fileURLToPath } from \"node:url\";\r\n\r\nimport koffi from \"koffi\";\r\n\r\nfunction resolveDirname(): string {\r\n return path.dirname(fileURLToPath(import.meta.url));\r\n}\r\n\r\nfunction libPath(): string {\r\n const base = path.join(resolveDirname(), \"..\", \"build\");\r\n if (process.platform === \"win32\") return path.join(base, \"messagix.dll\");\r\n if (process.platform === \"darwin\") return path.join(base, \"messagix.dylib\");\r\n return path.join(base, \"messagix.so\");\r\n}\r\n\r\nconst LIB_FILE = libPath();\r\nif (!fs.existsSync(LIB_FILE)) {\r\n throw new Error(`Native library not found at ${LIB_FILE}. Run: npm run build:go`);\r\n}\r\n\r\nconst lib = koffi.load(LIB_FILE);\r\n\r\nconst mk = (ret: string, name: string, args: string[]) => lib.func(name, ret, args);\r\n\r\nconst fns = {\r\n MxFreeCString: mk(\"void\", \"MxFreeCString\", [\"char*\"]),\r\n MxNewClient: mk(\"str\", \"MxNewClient\", [\"str\"]),\r\n MxConnect: mk(\"str\", \"MxConnect\", [\"str\"]),\r\n MxConnectE2EE: mk(\"str\", \"MxConnectE2EE\", [\"str\"]),\r\n MxDisconnect: mk(\"str\", \"MxDisconnect\", [\"str\"]),\r\n MxIsConnected: mk(\"str\", \"MxIsConnected\", [\"str\"]),\r\n MxSendMessage: mk(\"str\", \"MxSendMessage\", [\"str\"]),\r\n MxSendReaction: mk(\"str\", \"MxSendReaction\", [\"str\"]),\r\n MxEditMessage: mk(\"str\", \"MxEditMessage\", [\"str\"]),\r\n MxUnsendMessage: mk(\"str\", \"MxUnsendMessage\", [\"str\"]),\r\n MxSendTyping: mk(\"str\", \"MxSendTyping\", [\"str\"]),\r\n MxMarkRead: mk(\"str\", \"MxMarkRead\", [\"str\"]),\r\n MxUploadMedia: mk(\"str\", \"MxUploadMedia\", [\"str\"]),\r\n MxSendImage: mk(\"str\", \"MxSendImage\", [\"str\"]),\r\n MxSendVideo: mk(\"str\", \"MxSendVideo\", [\"str\"]),\r\n MxSendVoice: mk(\"str\", \"MxSendVoice\", [\"str\"]),\r\n MxSendFile: mk(\"str\", \"MxSendFile\", [\"str\"]),\r\n MxSendSticker: mk(\"str\", \"MxSendSticker\", [\"str\"]),\r\n MxCreateThread: mk(\"str\", \"MxCreateThread\", [\"str\"]),\r\n MxGetUserInfo: mk(\"str\", \"MxGetUserInfo\", [\"str\"]),\r\n MxSetGroupPhoto: mk(\"str\", \"MxSetGroupPhoto\", [\"str\"]),\r\n MxRenameThread: mk(\"str\", \"MxRenameThread\", [\"str\"]),\r\n MxMuteThread: mk(\"str\", \"MxMuteThread\", [\"str\"]),\r\n MxDeleteThread: mk(\"str\", \"MxDeleteThread\", [\"str\"]),\r\n MxSearchUsers: mk(\"str\", \"MxSearchUsers\", [\"str\"]),\r\n MxPollEvents: mk(\"str\", \"MxPollEvents\", [\"str\"]),\r\n MxSendE2EEMessage: mk(\"str\", \"MxSendE2EEMessage\", [\"str\"]),\r\n MxSendE2EEReaction: mk(\"str\", \"MxSendE2EEReaction\", [\"str\"]),\r\n MxSendE2EETyping: mk(\"str\", \"MxSendE2EETyping\", [\"str\"]),\r\n MxEditE2EEMessage: mk(\"str\", \"MxEditE2EEMessage\", [\"str\"]),\r\n MxUnsendE2EEMessage: mk(\"str\", \"MxUnsendE2EEMessage\", [\"str\"]),\r\n MxGetDeviceData: mk(\"str\", \"MxGetDeviceData\", [\"str\"]),\r\n // E2EE Media functions\r\n MxSendE2EEImage: mk(\"str\", \"MxSendE2EEImage\", [\"str\"]),\r\n MxSendE2EEVideo: mk(\"str\", \"MxSendE2EEVideo\", [\"str\"]),\r\n MxSendE2EEAudio: mk(\"str\", \"MxSendE2EEAudio\", [\"str\"]),\r\n MxSendE2EEDocument: mk(\"str\", \"MxSendE2EEDocument\", [\"str\"]),\r\n MxSendE2EESticker: mk(\"str\", \"MxSendE2EESticker\", [\"str\"]),\r\n} as const;\r\n\r\ninterface JsonResp<T = unknown> {\r\n ok: boolean\r\n data?: T\r\n error?: string\r\n}\r\n\r\nfunction call<T>(fn: keyof typeof fns, payload: unknown): T {\r\n const input = JSON.stringify(payload);\r\n const bound = fns[fn] as (arg: string) => string;\r\n const out = bound(input);\r\n const data = JSON.parse(out) as JsonResp<T>;\r\n if (!data.ok) throw new Error(data.error || \"Unknown error\");\r\n return data.data as T;\r\n}\r\n\r\n// Async version that yields to event loop\r\nfunction callAsync<T>(fn: keyof typeof fns, payload: unknown): Promise<T> {\r\n return new Promise((resolve, reject) => {\r\n // Use setTimeout(0) to yield to event loop\r\n setTimeout(() => {\r\n try {\r\n const result = call<T>(fn, payload);\r\n resolve(result);\r\n }\r\n catch (err) {\r\n reject(err);\r\n }\r\n }, 0);\r\n });\r\n}\r\n\r\nexport const native = {\r\n newClient: (cfg: {\r\n cookies: Record<string, string>\r\n platform?: string\r\n devicePath?: string\r\n deviceData?: string\r\n logLevel?: string\r\n }) => call<{ handle: number }>(\"MxNewClient\", cfg),\r\n\r\n connect: (handle: number) =>\r\n call<{\r\n user: { id: number; name: string; username: string }\r\n initialData: { threads: unknown[]; messages: unknown[] }\r\n }>(\"MxConnect\", { handle }),\r\n\r\n connectE2EE: (handle: number) => callAsync<unknown>(\"MxConnectE2EE\", { handle }),\r\n\r\n disconnect: (handle: number) => call<unknown>(\"MxDisconnect\", { handle }),\r\n\r\n isConnected: (handle: number) =>\r\n call<{ connected: boolean; e2eeConnected: boolean }>(\"MxIsConnected\", { handle }),\r\n\r\n sendMessage: (\r\n handle: number,\r\n options: {\r\n threadId: number\r\n text: string\r\n replyToId?: string\r\n mentionIds?: number[]\r\n mentionOffsets?: number[]\r\n mentionLengths?: number[]\r\n attachmentFbIds?: number[]\r\n stickerId?: number\r\n url?: string\r\n isE2EE?: boolean\r\n e2eeChatJid?: string\r\n },\r\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendMessage\", { handle, options }),\r\n\r\n sendReaction: (handle: number, threadId: number, messageId: string, emoji: string) =>\r\n callAsync<unknown>(\"MxSendReaction\", { handle, threadId, messageId, emoji }),\r\n\r\n editMessage: (handle: number, messageId: string, newText: string) =>\r\n callAsync<unknown>(\"MxEditMessage\", { handle, messageId, newText }),\r\n\r\n unsendMessage: (handle: number, messageId: string) =>\r\n callAsync<unknown>(\"MxUnsendMessage\", { handle, messageId }),\r\n\r\n sendTyping: (\r\n handle: number,\r\n threadId: number,\r\n isTyping: boolean,\r\n isGroup: boolean,\r\n threadType: number,\r\n ) => callAsync<unknown>(\"MxSendTyping\", { handle, threadId, isTyping, isGroup, threadType }),\r\n\r\n markRead: (handle: number, threadId: number, watermarkTs?: number) =>\r\n callAsync<unknown>(\"MxMarkRead\", { handle, threadId, watermarkTs: watermarkTs || 0 }),\r\n\r\n uploadMedia: (\r\n handle: number,\r\n options: {\r\n threadId: number\r\n filename: string\r\n mimeType: string\r\n data: number[]\r\n isVoice?: boolean\r\n },\r\n ) => callAsync<{ fbId: number; filename: string }>(\"MxUploadMedia\", { handle, options }),\r\n\r\n sendImage: (\r\n handle: number,\r\n options: { threadId: number; data: number[]; filename: string; caption?: string },\r\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendImage\", { handle, options }),\r\n\r\n sendVideo: (\r\n handle: number,\r\n options: { threadId: number; data: number[]; filename: string; caption?: string },\r\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendVideo\", { handle, options }),\r\n\r\n sendVoice: (\r\n handle: number,\r\n options: { threadId: number; data: number[]; filename: string },\r\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendVoice\", { handle, options }),\r\n\r\n sendFile: (\r\n handle: number,\r\n options: {\r\n threadId: number\r\n data: number[]\r\n filename: string\r\n mimeType: string\r\n caption?: string\r\n },\r\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendFile\", { handle, options }),\r\n\r\n sendSticker: (handle: number, options: { threadId: number; stickerId: number }) =>\r\n callAsync<{ messageId: string; timestampMs: number }>(\"MxSendSticker\", { handle, options }),\r\n\r\n createThread: (handle: number, options: { userId: number }) =>\r\n callAsync<{ threadId: number }>(\"MxCreateThread\", { handle, options }),\r\n\r\n getUserInfo: (\r\n handle: number,\r\n options: { userId: number },\r\n ) =>\r\n callAsync<{\r\n id: number\r\n name: string\r\n firstName?: string\r\n username?: string\r\n profilePictureUrl?: string\r\n isMessengerUser?: boolean\r\n isVerified?: boolean\r\n gender?: number\r\n canViewerMessage?: boolean\r\n }>(\"MxGetUserInfo\", { handle, options }),\r\n\r\n setGroupPhoto: (handle: number, threadId: number, data: string, mimeType: string) =>\r\n callAsync<unknown>(\"MxSetGroupPhoto\", { handle, threadId, data, mimeType }),\r\n\r\n renameThread: (handle: number, options: { threadId: number; newName: string }) =>\r\n callAsync<unknown>(\"MxRenameThread\", { handle, options }),\r\n\r\n muteThread: (handle: number, options: { threadId: number; muteSeconds: number }) =>\r\n callAsync<unknown>(\"MxMuteThread\", { handle, options }),\r\n\r\n deleteThread: (handle: number, options: { threadId: number }) =>\r\n callAsync<unknown>(\"MxDeleteThread\", { handle, options }),\r\n\r\n searchUsers: (handle: number, options: { query: string }) =>\r\n callAsync<{ users: { id: number; name: string; username: string }[] }>(\"MxSearchUsers\", {\r\n handle,\r\n options,\r\n }),\r\n\r\n pollEvents: (handle: number, timeoutMs: number) =>\r\n callAsync<unknown>(\"MxPollEvents\", { handle, timeoutMs }),\r\n\r\n // E2EE functions\r\n sendE2EEMessage: (\r\n handle: number,\r\n chatJid: string,\r\n text: string,\r\n replyToId?: string,\r\n replyToSenderJid?: string,\r\n ) =>\r\n callAsync<{ messageId: string; timestampMs: number }>(\"MxSendE2EEMessage\", {\r\n handle,\r\n chatJid,\r\n text,\r\n replyToId,\r\n replyToSenderJid,\r\n }),\r\n\r\n sendE2EEReaction: (\r\n handle: number,\r\n chatJid: string,\r\n messageId: string,\r\n senderJid: string,\r\n emoji: string,\r\n ) => callAsync<unknown>(\"MxSendE2EEReaction\", { handle, chatJid, messageId, senderJid, emoji }),\r\n\r\n sendE2EETyping: (handle: number, chatJid: string, isTyping: boolean) =>\r\n callAsync<unknown>(\"MxSendE2EETyping\", { handle, chatJid, isTyping }),\r\n\r\n editE2EEMessage: (handle: number, chatJid: string, messageId: string, newText: string) =>\r\n callAsync<unknown>(\"MxEditE2EEMessage\", { handle, chatJid, messageId, newText }),\r\n\r\n unsendE2EEMessage: (handle: number, chatJid: string, messageId: string) =>\r\n callAsync<unknown>(\"MxUnsendE2EEMessage\", { handle, chatJid, messageId }),\r\n\r\n getDeviceData: (handle: number) =>\r\n call<{ deviceData: string }>(\"MxGetDeviceData\", { handle }),\r\n\r\n // E2EE Media functions\r\n sendE2EEImage: (\r\n handle: number,\r\n options: {\r\n chatJid: string\r\n data: number[]\r\n mimeType: string\r\n caption?: string\r\n width?: number\r\n height?: number\r\n replyToId?: string\r\n replyToSenderJid?: string\r\n },\r\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendE2EEImage\", { handle, options }),\r\n\r\n sendE2EEVideo: (\r\n handle: number,\r\n options: {\r\n chatJid: string\r\n data: number[]\r\n mimeType: string\r\n caption?: string\r\n width?: number\r\n height?: number\r\n duration?: number\r\n replyToId?: string\r\n replyToSenderJid?: string\r\n },\r\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendE2EEVideo\", { handle, options }),\r\n\r\n sendE2EEAudio: (\r\n handle: number,\r\n options: {\r\n chatJid: string\r\n data: number[]\r\n mimeType: string\r\n duration?: number\r\n ptt?: boolean // Push-to-talk (voice message)\r\n replyToId?: string\r\n replyToSenderJid?: string\r\n },\r\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendE2EEAudio\", { handle, options }),\r\n\r\n sendE2EEDocument: (\r\n handle: number,\r\n options: {\r\n chatJid: string\r\n data: number[]\r\n filename: string\r\n mimeType: string\r\n replyToId?: string\r\n replyToSenderJid?: string\r\n },\r\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendE2EEDocument\", { handle, options }),\r\n\r\n sendE2EESticker: (\r\n handle: number,\r\n options: {\r\n chatJid: string\r\n data: number[]\r\n mimeType: string\r\n replyToId?: string\r\n replyToSenderJid?: string\r\n },\r\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendE2EESticker\", { handle, options }),\r\n\r\n unload: () => lib.unload(),\r\n};\r\n","/*\r\r\n * meta-messenger.js, Unofficial Meta Messenger Chat API for NodeJS\r\r\n * Copyright (c) 2026 Elysia and contributors\r\r\n */\r\n\r\n/**\r\n * Event types emitted by the client\r\n */\r\nexport type EventType =\r\n | \"ready\"\r\n | \"reconnected\"\r\n | \"disconnected\"\r\n | \"error\"\r\n | \"message\"\r\n | \"messageEdit\"\r\n | \"messageUnsend\"\r\n | \"reaction\"\r\n | \"typing\"\r\n | \"readReceipt\"\r\n | \"e2eeConnected\"\r\n | \"e2eeMessage\"\r\n | \"e2eeReaction\"\r\n | \"e2eeReceipt\"\r\n | \"deviceDataChanged\"\r\n\r\n/**\r\n * Base event interface\r\n */\r\nexport interface BaseEvent {\r\n type: EventType\r\n timestamp: number\r\n}\r\n\r\n/**\r\n * Ready event - emitted when connected to Messenger\r\n */\r\nexport interface ReadyEvent extends BaseEvent {\r\n type: \"ready\"\r\n data: {\r\n isNewSession: boolean\r\n }\r\n}\r\n\r\n/**\r\n * Reconnected event\r\n */\r\nexport interface ReconnectedEvent extends BaseEvent {\r\n type: \"reconnected\"\r\n}\r\n\r\n/**\r\n * Disconnected event\r\n */\r\nexport interface DisconnectedEvent extends BaseEvent {\r\n type: \"disconnected\"\r\n data?: {\r\n isE2EE?: boolean\r\n }\r\n}\r\n\r\n/**\r\n * Error event\r\n */\r\nexport interface ErrorEvent extends BaseEvent {\r\n type: \"error\"\r\n data: {\r\n message: string\r\n code?: number\r\n }\r\n}\r\n\r\n/**\r\n * Message event - new message received\r\n */\r\nexport interface MessageEvent extends BaseEvent {\r\n type: \"message\"\r\n data: Message\r\n}\r\n\r\n/**\r\n * Message edit event\r\n */\r\nexport interface MessageEditEvent extends BaseEvent {\r\n type: \"messageEdit\"\r\n data: {\r\n messageId: string\r\n threadId: number\r\n newText: string\r\n editCount?: number\r\n timestampMs?: number\r\n }\r\n}\r\n\r\n/**\r\n * Message unsend event\r\n */\r\nexport interface MessageUnsendEvent extends BaseEvent {\r\n type: \"messageUnsend\"\r\n data: {\r\n messageId: string\r\n threadId: number\r\n }\r\n}\r\n\r\n/**\r\n * Reaction event\r\n */\r\nexport interface ReactionEvent extends BaseEvent {\r\n type: \"reaction\"\r\n data: {\r\n messageId: string\r\n threadId: number\r\n actorId: number\r\n reaction: string\r\n timestampMs: number\r\n }\r\n}\r\n\r\n/**\r\n * Typing event\r\n */\r\nexport interface TypingEvent extends BaseEvent {\r\n type: \"typing\"\r\n data: {\r\n threadId: number\r\n senderId: number\r\n isTyping: boolean\r\n }\r\n}\r\n\r\n/**\r\n * Read receipt event\r\n */\r\nexport interface ReadReceiptEvent extends BaseEvent {\r\n type: \"readReceipt\"\r\n data: {\r\n threadId: number\r\n readerId: number\r\n readWatermarkTimestampMs: number\r\n timestampMs?: number\r\n }\r\n}\r\n\r\n/**\r\n * E2EE connected event\r\n */\r\nexport interface E2EEConnectedEvent extends BaseEvent {\r\n type: \"e2eeConnected\"\r\n}\r\n\r\n/**\r\n * E2EE message event\r\n */\r\nexport interface E2EEMessageEvent extends BaseEvent {\r\n type: \"e2eeMessage\"\r\n data: E2EEMessage\r\n}\r\n\r\n/**\r\n * E2EE reaction event\r\n */\r\nexport interface E2EEReactionEvent extends BaseEvent {\r\n type: \"e2eeReaction\"\r\n data: {\r\n messageId: string\r\n chatJid: string\r\n senderJid: string\r\n reaction: string\r\n }\r\n}\r\n\r\n/**\r\n * E2EE receipt event\r\n */\r\nexport interface E2EEReceiptEvent extends BaseEvent {\r\n type: \"e2eeReceipt\"\r\n data: {\r\n type: string\r\n chat: string\r\n sender: string\r\n messageIds: string[]\r\n }\r\n}\r\n\r\n/**\r\n * Device data changed event - emitted when E2EE device data changes (only when using deviceData option)\r\n */\r\nexport interface DeviceDataChangedEvent extends BaseEvent {\r\n type: \"deviceDataChanged\"\r\n data: {\r\n deviceData: string\r\n }\r\n}\r\n\r\n/**\r\n * Union of all events\r\n */\r\nexport type ClientEvent =\r\n | ReadyEvent\r\n | ReconnectedEvent\r\n | DisconnectedEvent\r\n | ErrorEvent\r\n | MessageEvent\r\n | MessageEditEvent\r\n | MessageUnsendEvent\r\n | ReactionEvent\r\n | TypingEvent\r\n | ReadReceiptEvent\r\n | E2EEConnectedEvent\r\n | E2EEMessageEvent\r\n | E2EEReactionEvent\r\n | E2EEReceiptEvent\r\n | DeviceDataChangedEvent\r\n\r\n/**\r\n * User information\r\n */\r\nexport interface User {\r\n id: number\r\n name: string\r\n username: string\r\n}\r\n\r\n/**\r\n * Thread/conversation\r\n */\r\nexport interface Thread {\r\n id: number\r\n type: ThreadType\r\n name: string\r\n lastActivityTimestampMs: number\r\n snippet: string\r\n}\r\n\r\n/**\r\n * Thread types\r\n */\r\nexport enum ThreadType {\r\n ONE_TO_ONE = 1,\r\n GROUP = 2,\r\n PAGE = 3,\r\n MARKETPLACE = 4,\r\n ENCRYPTED_ONE_TO_ONE = 7,\r\n ENCRYPTED_GROUP = 8,\r\n}\r\n\r\n/**\r\n * Attachment type\r\n */\r\nexport type AttachmentType = \"image\" | \"video\" | \"audio\" | \"file\" | \"sticker\" | \"gif\" | \"voice\" | \"location\" | \"link\"\r\n\r\n/**\r\n * Media attachment\r\n */\r\nexport interface Attachment {\r\n type: AttachmentType\r\n url?: string\r\n fileName?: string\r\n mimeType?: string\r\n fileSize?: number\r\n width?: number\r\n height?: number\r\n duration?: number // in seconds for audio/video\r\n stickerId?: number\r\n latitude?: number\r\n longitude?: number\r\n previewUrl?: string\r\n // For E2EE media download\r\n mediaKey?: string // base64 encoded\r\n mediaSha256?: string // base64 encoded\r\n directPath?: string\r\n}\r\n\r\n/**\r\n * Reply info\r\n */\r\nexport interface ReplyTo {\r\n messageId: string\r\n senderId?: number\r\n text?: string\r\n}\r\n\r\n/**\r\n * Mention in message\r\n */\r\nexport interface Mention {\r\n userId: number\r\n offset: number\r\n length: number\r\n type?: \"user\" | \"page\" | \"group\"\r\n}\r\n\r\n/**\r\n * Message\r\n */\r\nexport interface Message {\r\n id: string\r\n threadId: number\r\n senderId: number\r\n text: string\r\n timestampMs: number\r\n isE2EE?: boolean\r\n chatJid?: string\r\n senderJid?: string\r\n attachments?: Attachment[]\r\n replyTo?: ReplyTo\r\n mentions?: Mention[]\r\n isAdminMsg?: boolean\r\n}\r\n\r\n/**\r\n * E2EE Message\r\n */\r\nexport interface E2EEMessage {\r\n id: string\r\n threadId: number\r\n chatJid: string\r\n senderJid: string\r\n senderId: number\r\n text: string\r\n timestampMs: number\r\n attachments?: Attachment[]\r\n replyTo?: ReplyTo\r\n mentions?: Mention[]\r\n}\r\n\r\n/**\r\n * Read receipt event data\r\n */\r\nexport interface ReadReceiptData {\r\n threadId: number\r\n readerId: number\r\n readWatermarkTimestampMs: number\r\n timestampMs?: number\r\n}\r\n\r\n/**\r\n * Initial data received on connect\r\n */\r\nexport interface InitialData {\r\n threads: Thread[]\r\n messages: Message[]\r\n}\r\n\r\n/**\r\n * Platform type\r\n */\r\nexport type Platform = \"facebook\" | \"messenger\" | \"instagram\"\r\n\r\n/**\r\n * Log level\r\n */\r\nexport type LogLevel = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"none\"\r\n\r\n/**\r\n * Cookies required for authentication\r\n */\r\nexport interface Cookies {\r\n c_user: string\r\n xs: string\r\n datr?: string\r\n fr?: string\r\n [key: string]: string | undefined\r\n}\r\n\r\n/**\r\n * Client options\r\n */\r\nexport interface ClientOptions {\r\n /** Platform to connect to (Only tested on Facebook) */\r\n platform?: Platform\r\n /** Path to E2EE device store (if not using deviceData) */\r\n devicePath?: string\r\n /** E2EE device data as JSON string (takes priority over devicePath) */\r\n deviceData?: string\r\n /** Log level */\r\n logLevel?: LogLevel\r\n /** Enable E2EE */\r\n enableE2EE?: boolean\r\n /** Auto reconnect on disconnect */\r\n autoReconnect?: boolean\r\n}\r\n\r\n/**\r\n * Send message options\r\n */\r\nexport interface SendMessageOptions {\r\n /** Text content */\r\n text: string\r\n /** Reply to message ID */\r\n replyToId?: string\r\n /** User IDs to mention */\r\n mentions?: Array<{\r\n userId: number\r\n offset: number\r\n length: number\r\n }>\r\n}\r\n\r\n/**\r\n * Send message result\r\n */\r\nexport interface SendMessageResult {\r\n messageId: string\r\n timestampMs: number\r\n}\r\n\r\n/**\r\n * Upload media result\r\n */\r\nexport interface UploadMediaResult {\r\n fbId: number\r\n filename: string\r\n}\r\n\r\n/**\r\n * Search user result\r\n */\r\nexport interface SearchUserResult {\r\n id: number\r\n name: string\r\n username: string\r\n}\r\n\r\n/**\r\n * Create thread result (1:1 chat)\r\n */\r\nexport interface CreateThreadResult {\r\n threadId: number\r\n}\r\n\r\n/**\r\n * User information\r\n */\r\nexport interface UserInfo {\r\n id: number\r\n name: string\r\n firstName?: string\r\n username?: string\r\n profilePictureUrl?: string\r\n isMessengerUser?: boolean\r\n isVerified?: boolean\r\n gender?: number\r\n canViewerMessage?: boolean\r\n}\r\n","/*\r\r\n * meta-messenger.js, Unofficial Meta Messenger Chat API for NodeJS\r\r\n * Copyright (c) 2026 Elysia and contributors\r\r\n */\r\n\r\n/**\r\n * Utility class for cookie parsing and conversion\r\n *\r\n * Supports multiple cookie formats:\r\n * - C3C UFC Utility / EditThisCookie (array of cookie objects)\r\n * - Simple object format { name: value }\r\n * - Netscape/HTTP cookie file format\r\n * - Cookie header string format\r\n * - Base64 encoded cookies\r\n */\r\n\r\nimport type { Cookies } from \"./types.js\";\r\n\r\n/**\r\n * Cookie object format (C3C UFC Utility / EditThisCookie style)\r\n */\r\nexport interface CookieObject {\r\n name: string\r\n value: string\r\n domain?: string\r\n path?: string\r\n expires?: number | string\r\n expirationDate?: number\r\n httpOnly?: boolean\r\n secure?: boolean\r\n sameSite?: string\r\n hostOnly?: boolean\r\n session?: boolean\r\n}\r\n\r\n/**\r\n * Netscape cookie file line format\r\n */\r\nexport interface NetscapeCookie {\r\n domain: string\r\n flag: boolean\r\n path: string\r\n secure: boolean\r\n expiration: number\r\n name: string\r\n value: string\r\n}\r\n\r\n/**\r\n * Static utility class for cookie operations\r\n * @example\r\n * ```typescript\r\n * import { Utils } from 'meta-messenger.js'\r\n *\r\n * // Parse any cookie format\r\n * const cookies = Utils.parseCookies(rawData)\r\n *\r\n * // Convert cookies to header string\r\n * const header = Utils.toCookieString(cookies)\r\n * ```\r\n */\r\nexport class Utils extends null {\r\n /**\r\n * Parse cookies from various formats\r\n * Automatically detects the format and parses accordingly\r\n *\r\n * @param input - Cookie data in any supported format\r\n * @returns Parsed cookies object\r\n */\r\n static parseCookies(input: string | CookieObject[] | Record<string, string>): Cookies {\r\n // Already a simple object\r\n if (typeof input === \"object\" && !Array.isArray(input)) {\r\n return input as Cookies;\r\n }\r\n\r\n // Array of cookie objects (C3C UFC Utility / EditThisCookie)\r\n if (Array.isArray(input)) {\r\n return Utils.fromCookieArray(input);\r\n }\r\n\r\n // String input - detect format\r\n if (typeof input === \"string\") {\r\n const trimmed = input.trim();\r\n\r\n // Try Base64 first\r\n if (Utils.isBase64(trimmed)) {\r\n try {\r\n const decoded = Buffer.from(trimmed, \"base64\").toString(\"utf-8\");\r\n return Utils.parseCookies(decoded);\r\n }\r\n catch {\r\n // Not valid base64, continue with other formats\r\n }\r\n }\r\n\r\n // Try JSON (array or object)\r\n if (trimmed.startsWith(\"[\") || trimmed.startsWith(\"{\")) {\r\n try {\r\n const parsed = JSON.parse(trimmed);\r\n return Utils.parseCookies(parsed);\r\n }\r\n catch {\r\n // Not valid JSON, continue with other formats\r\n }\r\n }\r\n\r\n // Netscape cookie file format (starts with # or domain)\r\n if (trimmed.includes(\"\\t\") && (trimmed.startsWith(\"#\") || trimmed.includes(\".facebook.com\") || trimmed.includes(\".messenger.com\"))) {\r\n return Utils.fromNetscape(trimmed);\r\n }\r\n\r\n // Cookie header string format (name=value; name2=value2)\r\n if (trimmed.includes(\"=\")) {\r\n return Utils.fromCookieString(trimmed);\r\n }\r\n }\r\n\r\n throw new Error(\"Unable to parse cookies: unknown format\");\r\n }\r\n\r\n /**\r\n * Parse cookies from C3C UFC Utility / EditThisCookie array format\r\n *\r\n * @param cookies - Array of cookie objects\r\n * @returns Parsed cookies object\r\n *\r\n * @example\r\n * ```typescript\r\n * const cookies = Utils.fromCookieArray([\r\n * { name: 'c_user', value: '123456' },\r\n * { name: 'xs', value: 'abc...' }\r\n * ])\r\n * ```\r\n */\r\n static fromCookieArray(cookies: CookieObject[]): Cookies {\r\n const result: Record<string, string> = {};\r\n for (const cookie of cookies) {\r\n if (cookie.name && cookie.value !== undefined) {\r\n result[cookie.name] = String(cookie.value);\r\n }\r\n }\r\n return result as Cookies;\r\n }\r\n\r\n /**\r\n * Parse cookies from cookie header string format\r\n *\r\n * @param cookieString - Cookie string (e.g., \"name1=value1; name2=value2\")\r\n * @returns Parsed cookies object\r\n *\r\n * @example\r\n * ```typescript\r\n * const cookies = Utils.fromCookieString('c_user=123456; xs=abc...; datr=xyz...')\r\n * ```\r\n */\r\n static fromCookieString(cookieString: string): Cookies {\r\n const result: Record<string, string> = {};\r\n const pairs = cookieString.split(/;\\s*/);\r\n\r\n for (const pair of pairs) {\r\n const [name, ...valueParts] = pair.split(\"=\");\r\n if (name && valueParts.length > 0) {\r\n const trimmedName = name.trim();\r\n const value = valueParts.join(\"=\").trim();\r\n if (trimmedName && value) {\r\n result[trimmedName] = value;\r\n }\r\n }\r\n }\r\n\r\n return result as Cookies;\r\n }\r\n\r\n /**\r\n * Parse cookies from Netscape/HTTP cookie file format\r\n *\r\n * @param content - Netscape cookie file content\r\n * @returns Parsed cookies object\r\n *\r\n * @example\r\n * ```typescript\r\n * const cookies = Utils.fromNetscape(`\r\n * # Netscape HTTP Cookie File\r\n * .facebook.com\tTRUE\t/\tTRUE\t1234567890\tc_user\t123456\r\n * .facebook.com\tTRUE\t/\tTRUE\t1234567890\txs\tabc...\r\n * `)\r\n * ```\r\n */\r\n static fromNetscape(content: string): Cookies {\r\n const result: Record<string, string> = {};\r\n const lines = content.split(\"\\n\");\r\n\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n\r\n // Skip comments and empty lines\r\n if (!trimmed || trimmed.startsWith(\"#\")) {\r\n continue;\r\n }\r\n\r\n // Parse tab-separated values\r\n const parts = trimmed.split(\"\\t\");\r\n if (parts.length >= 7) {\r\n const name = parts[5];\r\n const value = parts[6];\r\n if (name && value) {\r\n result[name] = value;\r\n }\r\n }\r\n }\r\n\r\n return result as Cookies;\r\n }\r\n\r\n /**\r\n * Parse cookies from Base64 encoded string\r\n *\r\n * @param base64 - Base64 encoded cookie data\r\n * @returns Parsed cookies object\r\n */\r\n static fromBase64(base64: string): Cookies {\r\n const decoded = Buffer.from(base64, \"base64\").toString(\"utf-8\");\r\n return Utils.parseCookies(decoded);\r\n }\r\n\r\n /**\r\n * Convert cookies object to cookie header string\r\n *\r\n * @param cookies - Cookies object\r\n * @returns Cookie header string\r\n *\r\n * @example\r\n * ```typescript\r\n * const header = Utils.toCookieString({ c_user: '123456', xs: 'abc...' })\r\n * // Returns: \"c_user=123456; xs=abc...\"\r\n * ```\r\n */\r\n static toCookieString(cookies: Cookies): string {\r\n return Object.entries(cookies)\r\n .map(([name, value]) => `${name}=${value}`)\r\n .join(\"; \");\r\n }\r\n\r\n /**\r\n * Convert cookies object to array format (C3C UFC Utility style)\r\n *\r\n * @param cookies - Cookies object\r\n * @param domain - Cookie domain (default: .facebook.com)\r\n * @returns Array of cookie objects\r\n *\r\n * @example\r\n * ```typescript\r\n * const arr = Utils.toCookieArray({ c_user: '123456', xs: 'abc...' })\r\n * ```\r\n */\r\n static toCookieArray(cookies: Cookies, domain = \".facebook.com\"): CookieObject[] {\r\n return Object.entries(cookies)\r\n .filter(([_, value]) => value !== undefined)\r\n .map(([name, value]) => ({\r\n name,\r\n value: value as string,\r\n domain,\r\n path: \"/\",\r\n secure: true,\r\n httpOnly: true,\r\n }));\r\n }\r\n\r\n /**\r\n * Convert cookies object to Netscape format\r\n *\r\n * @param cookies - Cookies object\r\n * @param domain - Cookie domain (default: .facebook.com)\r\n * @returns Netscape cookie file content\r\n */\r\n static toNetscape(cookies: Cookies, domain = \".facebook.com\"): string {\r\n const lines = [\"# Netscape HTTP Cookie File\", \"# Generated by meta-messenger.js\", \"\"];\r\n\r\n for (const [name, value] of Object.entries(cookies)) {\r\n // domain, flag, path, secure, expiration, name, value\r\n const expiration = Math.floor(Date.now() / 1000) + 365 * 24 * 60 * 60; // 1 year\r\n lines.push(`${domain}\\tTRUE\\t/\\tTRUE\\t${expiration}\\t${name}\\t${value}`);\r\n }\r\n\r\n return lines.join(\"\\n\");\r\n }\r\n\r\n /**\r\n * Convert cookies to Base64 encoded JSON\r\n *\r\n * @param cookies - Cookies object\r\n * @returns Base64 encoded string\r\n */\r\n static toBase64(cookies: Cookies): string {\r\n return Buffer.from(JSON.stringify(cookies)).toString(\"base64\");\r\n }\r\n\r\n /**\r\n * Filter cookies to only essential ones for Facebook/Messenger\r\n *\r\n * @param cookies - Cookies object\r\n * @returns Filtered cookies with only essential keys\r\n */\r\n static filterEssential(cookies: Cookies): Cookies {\r\n const essential = [\"c_user\", \"xs\", \"datr\", \"fr\", \"sb\", \"wd\", \"presence\"];\r\n const result: Record<string, string> = {};\r\n\r\n for (const key of essential) {\r\n if (cookies[key]) {\r\n result[key] = cookies[key] as string;\r\n }\r\n }\r\n\r\n return result as Cookies;\r\n }\r\n\r\n /**\r\n * Validate that cookies contain required fields\r\n *\r\n * @param cookies - Cookies object\r\n * @returns True if cookies are valid\r\n */\r\n static validate(cookies: Cookies): boolean {\r\n const required = [\"c_user\", \"xs\"];\r\n return required.every(key => cookies[key] && cookies[key].length > 0);\r\n }\r\n\r\n /**\r\n * Get missing required cookies\r\n *\r\n * @param cookies - Cookies object\r\n * @returns Array of missing cookie names\r\n */\r\n static getMissing(cookies: Cookies): string[] {\r\n const required = [\"c_user\", \"xs\"];\r\n return required.filter(key => !cookies[key] || cookies[key].length === 0);\r\n }\r\n\r\n /**\r\n * Check if a string is valid Base64\r\n */\r\n private static isBase64(str: string): boolean {\r\n if (str.length < 4) return false;\r\n // Check if string contains only valid base64 characters\r\n const base64Regex = /^[A-Za-z0-9+/]+=*$/;\r\n if (!base64Regex.test(str)) return false;\r\n // Try to detect if it's likely base64 (not a simple word)\r\n return str.length > 20 && str.length % 4 === 0;\r\n }\r\n}\r\n","/*\r\r\n * meta-messenger.js, Unofficial Meta Messenger Chat API for NodeJS\r\r\n * Copyright (c) 2026 Elysia and contributors\r\r\n */\r\n\r\n/**\r\n * meta-messenger.js - TypeScript wrapper for Facebook Messenger with E2EE support\r\n *\r\n * @example\r\n * ```typescript\r\n * import { Client, login } from 'meta-messenger.js'\r\n *\r\n * // Method 1: Using Client class directly\r\n * const client = new Client({\r\n * c_user: 'your_user_id',\r\n * xs: 'your_xs_cookie',\r\n * datr: 'your_datr_cookie',\r\n * fr: 'your_fr_cookie'\r\n * })\r\n *\r\n * client.on('message', (message) => {\r\n * console.log('New message:', message)\r\n * if (message.text === 'ping') {\r\n * client.sendMessage(message.threadId, 'pong')\r\n * }\r\n * })\r\n *\r\n * await client.connect()\r\n *\r\n * // Method 2: Using login function (facebook-chat-api style)\r\n * const api = await login({\r\n * c_user: 'your_user_id',\r\n * xs: 'your_xs_cookie',\r\n * datr: 'your_datr_cookie',\r\n * fr: 'your_fr_cookie'\r\n * })\r\n *\r\n * api.on('message', (message) => {\r\n * console.log('Got message:', message.text)\r\n * })\r\n * ```\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nexport type { ClientEventMap } from \"./client.js\";\r\nexport { Client } from \"./client.js\";\r\nexport {\r\n type BaseEvent,\r\n type ClientEvent,\r\n type ClientOptions,\r\n type Cookies,\r\n type CreateThreadResult,\r\n type DisconnectedEvent,\r\n type E2EEConnectedEvent,\r\n type E2EEMessage,\r\n type E2EEMessageEvent,\r\n type E2EEReactionEvent,\r\n type E2EEReceiptEvent,\r\n type ErrorEvent,\r\n // Types\r\n type EventType,\r\n type InitialData,\r\n type LogLevel,\r\n type Message,\r\n type MessageEditEvent,\r\n type MessageEvent,\r\n type MessageUnsendEvent,\r\n type Platform,\r\n type ReactionEvent,\r\n type ReadyEvent,\r\n type ReconnectedEvent,\r\n type SearchUserResult,\r\n type SendMessageOptions,\r\n type SendMessageResult,\r\n type Thread,\r\n // Enums\r\n ThreadType,\r\n type TypingEvent,\r\n type UploadMediaResult,\r\n type User,\r\n type UserInfo,\r\n} from \"./types.js\";\r\nexport { type CookieObject, Utils } from \"./utils.js\";\r\n\r\nimport { Client } from \"./client.js\";\r\nimport type { ClientOptions, Cookies } from \"./types.js\";\r\n\r\n/**\r\n * Login to Facebook Messenger (E2EE disabled for simplicity)\r\n *\r\n * @param cookies - Authentication cookies\r\n * @param options - Client options\r\n * @returns Connected client instance\r\n *\r\n * @example\r\n * ```typescript\r\n * const api = await login({\r\n * c_user: 'your_user_id',\r\n * xs: 'your_xs_cookie',\r\n * datr: 'your_datr_cookie',\r\n * fr: 'your_fr_cookie'\r\n * })\r\n *\r\n * console.log('Logged in as:', api.user?.name)\r\n *\r\n * api.on('message', async (message) => {\r\n * if (message.senderId !== api.currentUserId) {\r\n * await api.sendMessage(message.threadId, 'Hello!')\r\n * }\r\n * })\r\n * ```\r\n */\r\nexport async function login(\r\n cookies: Cookies,\r\n options?: ClientOptions,\r\n): Promise<Client> {\r\n const client = new Client(cookies, options);\r\n await client.connect();\r\n return client;\r\n}\r\n\r\n/**\r\n * Create a client without connecting\r\n *\r\n * @param cookies - Authentication cookies\r\n * @param options - Client options\r\n * @returns Client instance (not connected)\r\n */\r\nexport function createClient(\r\n cookies: Cookies,\r\n options?: ClientOptions,\r\n): Client {\r\n return new Client(cookies, options);\r\n}\r\n\r\n// Default export for convenience\r\nexport default { Client, login, createClient };\r\n"],"mappings":"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","names":["ThreadType"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/native.ts","../src/types.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["/*\n * meta-messenger.js, Unofficial Meta Messenger Chat API for NodeJS\n * Copyright (c) 2026 Elysia and contributors\n */\n\nimport { EventEmitter } from \"node:events\";\n\nimport { native } from \"./native.js\";\nimport type {\n ClientEvent,\n ClientOptions,\n Cookies,\n CreateThreadResult,\n E2EEMessage,\n InitialData,\n Message,\n SearchUserResult,\n SendMessageOptions,\n SendMessageResult,\n UploadMediaResult,\n User,\n UserInfo,\n} from \"./types.js\";\n\ndeclare class TypedEventEmitter<T> {\n on<K extends keyof T>(event: K, listener: (...args: T[K] extends unknown[] ? T[K] : never) => void): this;\n once<K extends keyof T>(event: K, listener: (...args: T[K] extends unknown[] ? T[K] : never) => void): this;\n off<K extends keyof T>(event: K, listener: (...args: T[K] extends unknown[] ? T[K] : never) => void): this;\n emit<K extends keyof T>(event: K, ...args: T[K] extends unknown[] ? T[K] : never): boolean;\n removeAllListeners<K extends keyof T>(event?: K): this;\n}\n\nexport interface ClientEventMap {\n ready: [{ isNewSession: boolean }];\n fullyReady: [];\n reconnected: [];\n disconnected: [{ isE2EE?: boolean }];\n error: [Error];\n message: [Message];\n messageEdit: [{ messageId: string; threadId: number; newText: string; editCount?: number; timestampMs?: number }];\n messageUnsend: [{ messageId: string; threadId: number }];\n reaction: [{ messageId: string; threadId: number; actorId: number; reaction: string; timestampMs?: number }];\n typing: [{ threadId: number; senderId: number; isTyping: boolean }];\n readReceipt: [{ threadId: number; readerId: number; readWatermarkTimestampMs: number; timestampMs?: number }];\n e2eeConnected: [];\n e2eeMessage: [E2EEMessage];\n e2eeReaction: [{ messageId: string; chatJid: string; senderJid: string; senderId?: number; reaction: string }];\n e2eeReceipt: [{ type: string; chat: string; sender: string; messageIds: string[] }];\n deviceDataChanged: [{ deviceData: string }];\n}\n\n/**\n * Demonstrates how to use the Client class to connect to Messenger and handle messages (E2EE disabled for simplicity).\n *\n * @example\n * ```typescript\n * import { Client } from 'meta-messenger.js'\n *\n * const client = new Client({\n * c_user: 'your_user_id',\n * xs: 'your_xs_cookie',\n * datr: 'your_datr_cookie',\n * fr: 'your_fr_cookie'\n * })\n *\n * client.on('message', (message) => {\n * console.log('New message:', message)\n * if (message.text === 'ping') {\n * client.sendMessage(message.threadId, { text: 'pong' })\n * }\n * })\n *\n * await client.connect()\n * ```\n */\nexport class Client extends (EventEmitter as new () => TypedEventEmitter<ClientEventMap>) {\n private handle: number | null = null;\n private options: ClientOptions;\n private cookies: Cookies;\n private _user: User | null = null;\n private _initialData: InitialData | null = null;\n private eventLoopRunning = false;\n private eventLoopAbort: AbortController | null = null;\n private _socketReady = false;\n private _e2eeConnected = false;\n private _fullyReadyEmitted = false;\n private pendingEvents: ClientEvent[] = [];\n\n /**\n * Create a new Messenger client\n *\n * @param cookies - Authentication cookies\n * @param options - Client options\n */\n constructor(cookies: Cookies, options: ClientOptions = {}) {\n super();\n this.cookies = cookies;\n this.options = {\n // ! todo: detect platform automatically\n platform: \"facebook\",\n logLevel: \"none\",\n enableE2EE: true,\n autoReconnect: true,\n ...options,\n };\n }\n\n /**\n * Get the current user info\n */\n get user(): User | null {\n return this._user;\n }\n\n /**\n * Get the current user's Facebook ID\n */\n get currentUserId(): number | null {\n return this._user?.id ?? null;\n }\n\n /**\n * Get initial sync data (threads and messages)\n */\n get initialData(): InitialData | null {\n return this._initialData;\n }\n\n /**\n * Check if client is fully ready (socket ready + E2EE connected if enabled)\n */\n get isFullyReady(): boolean {\n if (!this._socketReady) return false;\n if (this.options.enableE2EE && !this._e2eeConnected) return false;\n return true;\n }\n\n /**\n * Check if client is connected\n */\n get isConnected(): boolean {\n if (!this.handle) return false;\n try {\n const status = native.isConnected(this.handle);\n return status.connected;\n } catch {\n return false;\n }\n }\n\n /**\n * Check if E2EE is connected\n */\n get isE2EEConnected(): boolean {\n if (!this.handle) return false;\n try {\n const status = native.isConnected(this.handle);\n return status.e2eeConnected;\n } catch {\n return false;\n }\n }\n\n /**\n * Connect to Messenger\n *\n * @returns User info and initial data\n */\n async connect(): Promise<{ user: User; initialData: InitialData }> {\n // Create native client\n const { handle } = native.newClient({\n cookies: this.cookies as Record<string, string>,\n platform: this.options.platform,\n devicePath: this.options.devicePath,\n deviceData: this.options.deviceData,\n logLevel: this.options.logLevel,\n });\n this.handle = handle;\n\n // Connect\n const result = native.connect(handle);\n this._user = result.user as User;\n this._initialData = result.initialData as InitialData;\n\n // Start event loop\n this.startEventLoop();\n\n // Connect E2EE if enabled\n if (this.options.enableE2EE) {\n this.connectE2EE().catch(err => {\n this.emit(\"error\", err);\n });\n }\n\n return {\n user: this._user,\n initialData: this._initialData,\n };\n }\n\n /**\n * Connect E2EE (end-to-end encryption)\n * @warn This Promise is not resolved after the connection setup is completed; instead, it is resolved after the function finishes executing.\\\n * You should not rely on this Promise to wait for the E2EE connection to be fully established.\n */\n async connectE2EE(): Promise<void> {\n if (!this.handle) throw new Error(\"Not connected\");\n await native.connectE2EE(this.handle);\n }\n\n /**\n * Disconnect from Messenger\n */\n async disconnect(): Promise<void> {\n this.stopEventLoop();\n if (this.handle) {\n native.disconnect(this.handle);\n this.handle = null;\n }\n }\n\n /**\n * Send a text message\n *\n * @param threadId - Thread ID to send to\n * @param options - Message options (text, reply, mentions)\n * @returns Send result with message ID\n */\n async sendMessage(threadId: number, options: SendMessageOptions | string): Promise<SendMessageResult> {\n if (!this.handle) throw new Error(\"Not connected\");\n\n const opts = typeof options === \"string\" ? { text: options } : options;\n\n return native.sendMessage(this.handle, {\n threadId,\n text: opts.text,\n replyToId: opts.replyToId,\n mentionIds: opts.mentions?.map(m => m.userId),\n mentionOffsets: opts.mentions?.map(m => m.offset),\n mentionLengths: opts.mentions?.map(m => m.length),\n });\n }\n\n /**\n * Send / Remove a reaction to a message\n *\n * @param threadId - Thread ID\n * @param messageId - Message ID to react to\n * @param emoji - Reaction emoji (to remove, simply omit this parameter)\n */\n async sendReaction(threadId: number, messageId: string, emoji?: string): Promise<void> {\n if (!this.handle) throw new Error(\"Not connected\");\n await native.sendReaction(this.handle, threadId, messageId, emoji || \"\");\n }\n\n /**\n * Edit a message\n *\n * @param messageId - Message ID to edit\n * @param newText - New text content\n */\n async editMessage(messageId: string, newText: string): Promise<void> {\n if (!this.handle) throw new Error(\"Not connected\");\n await native.editMessage(this.handle, messageId, newText);\n }\n\n /**\n * Unsend/delete a message\n *\n * @param messageId - Message ID to unsend\n */\n async unsendMessage(messageId: string): Promise<void> {\n if (!this.handle) throw new Error(\"Not connected\");\n await native.unsendMessage(this.handle, messageId);\n }\n\n /**\n * Send typing indicator\n *\n * @param threadId - Thread ID\n * @param isTyping - Whether typing or not\n * @param isGroup - Whether it's a group chat\n */\n async sendTypingIndicator(threadId: number, isTyping: boolean = true, isGroup: boolean = false): Promise<void> {\n if (!this.handle) throw new Error(\"Not connected\");\n await native.sendTyping(this.handle, threadId, isTyping, isGroup, isGroup ? 2 : 1);\n }\n\n /**\n * Mark messages as read\n *\n * @param threadId - Thread ID\n * @param watermarkTs - Timestamp to mark read up to (optional)\n */\n async markAsRead(threadId: number, watermarkTs?: number): Promise<void> {\n if (!this.handle) throw new Error(\"Not connected\");\n await native.markRead(this.handle, threadId, watermarkTs);\n }\n\n /**\n * Upload media to Messenger\n *\n * @param threadId - Thread ID\n * @param data - File data as Buffer\n * @param filename - Filename\n * @param mimeType - MIME type\n * @param isVoice - Whether it's a voice message\n * @returns Upload result with Facebook ID\n */\n async uploadMedia(\n threadId: number,\n data: Buffer,\n filename: string,\n mimeType: string,\n isVoice: boolean = false,\n ): Promise<UploadMediaResult> {\n if (!this.handle) throw new Error(\"Not connected\");\n return native.uploadMedia(this.handle, {\n threadId,\n filename,\n mimeType,\n data: Array.from(data),\n isVoice,\n });\n }\n\n /**\n * Send an image\n *\n * @param threadId - Thread ID\n * @param data - Image data as Buffer\n * @param filename - Filename\n * @param caption - Optional caption\n */\n async sendImage(threadId: number, data: Buffer, filename: string, caption?: string): Promise<SendMessageResult> {\n if (!this.handle) throw new Error(\"Not connected\");\n return native.sendImage(this.handle, {\n threadId,\n data: Array.from(data),\n filename,\n caption,\n });\n }\n\n /**\n * Send a video\n *\n * @param threadId - Thread ID\n * @param data - Video data as Buffer\n * @param filename - Filename\n * @param caption - Optional caption\n */\n async sendVideo(threadId: number, data: Buffer, filename: string, caption?: string): Promise<SendMessageResult> {\n if (!this.handle) throw new Error(\"Not connected\");\n return native.sendVideo(this.handle, {\n threadId,\n data: Array.from(data),\n filename,\n caption,\n });\n }\n\n /**\n * Send a voice message\n *\n * @param threadId - Thread ID\n * @param data - Audio data as Buffer\n * @param filename - Filename\n */\n async sendVoice(threadId: number, data: Buffer, filename: string): Promise<SendMessageResult> {\n if (!this.handle) throw new Error(\"Not connected\");\n return native.sendVoice(this.handle, {\n threadId,\n data: Array.from(data),\n filename,\n });\n }\n\n /**\n * Send a file\n *\n * @param threadId - Thread ID\n * @param data - File data as Buffer\n * @param filename - Filename\n * @param mimeType - MIME type\n * @param caption - Optional caption\n */\n async sendFile(\n threadId: number,\n data: Buffer,\n filename: string,\n mimeType: string,\n caption?: string,\n ): Promise<SendMessageResult> {\n if (!this.handle) throw new Error(\"Not connected\");\n return native.sendFile(this.handle, {\n threadId,\n data: Array.from(data),\n filename,\n mimeType,\n caption,\n });\n }\n\n /**\n * Send a sticker\n *\n * @param threadId - Thread ID\n * @param stickerId - Sticker ID\n */\n async sendSticker(threadId: number, stickerId: number): Promise<SendMessageResult> {\n if (!this.handle) throw new Error(\"Not connected\");\n return native.sendSticker(this.handle, { threadId, stickerId });\n }\n\n /**\n * Create a 1:1 thread with a user\n *\n * @param userId - User ID to create thread with\n * @returns Created thread info\n */\n async createThread(userId: number): Promise<CreateThreadResult> {\n if (!this.handle) throw new Error(\"Not connected\");\n return native.createThread(this.handle, { userId });\n }\n\n /**\n * Get detailed information about a user\n *\n * @param userId - User ID\n * @returns User info\n */\n async getUserInfo(userId: number): Promise<UserInfo> {\n if (!this.handle) throw new Error(\"Not connected\");\n return native.getUserInfo(this.handle, { userId });\n }\n\n /**\n * Set group photo/avatar\n *\n * @param threadId - Thread ID\n * @param data - Image data as Buffer or base64 string\n * @param mimeType - MIME type (e.g., 'image/jpeg', 'image/png')\n *\n * @warn Cannot remove group photo. Messenger web doesn't have a remove option?\n */\n async setGroupPhoto(threadId: number, data: Buffer | string, mimeType: string = \"image/jpeg\"): Promise<void> {\n if (!this.handle) throw new Error(\"Not connected\");\n const base64 = Buffer.isBuffer(data) ? data.toString(\"base64\") : data;\n await native.setGroupPhoto(this.handle, threadId, base64, mimeType);\n }\n\n /**\n * Rename a group thread\n *\n * @param threadId - Thread ID\n * @param newName - New name\n */\n async renameThread(threadId: number, newName: string): Promise<void> {\n if (!this.handle) throw new Error(\"Not connected\");\n native.renameThread(this.handle, { threadId, newName });\n }\n\n /**\n * Mute a thread\n *\n * @param threadId - Thread ID\n * @param muteSeconds - Duration in seconds (-1 for forever, 0 to unmute)\n */\n async muteThread(threadId: number, muteSeconds: number = -1): Promise<void> {\n if (!this.handle) throw new Error(\"Not connected\");\n native.muteThread(this.handle, { threadId, muteSeconds });\n }\n\n /**\n * Unmute a thread\n *\n * @param threadId - Thread ID\n */\n async unmuteThread(threadId: number): Promise<void> {\n return this.muteThread(threadId, 0);\n }\n\n /**\n * Delete a thread\n *\n * @param threadId - Thread ID\n */\n async deleteThread(threadId: number): Promise<void> {\n if (!this.handle) throw new Error(\"Not connected\");\n native.deleteThread(this.handle, { threadId });\n }\n\n /**\n * Search for users\n *\n * @param query - Search query\n * @returns List of matching users\n */\n async searchUsers(query: string): Promise<SearchUserResult[]> {\n if (!this.handle) throw new Error(\"Not connected\");\n const result = await native.searchUsers(this.handle, { query });\n return result.users;\n }\n\n // ========== E2EE Methods ==========\n\n /**\n * Send an E2EE message\n *\n * @param chatJid - Chat JID\n * @param text - Message text\n * @param options - Optional: replyToId and replyToSenderJid for replies\n */\n async sendE2EEMessage(\n chatJid: string,\n text: string,\n options?: { replyToId?: string; replyToSenderJid?: string },\n ): Promise<SendMessageResult> {\n if (!this.handle) throw new Error(\"Not connected\");\n return native.sendE2EEMessage(this.handle, chatJid, text, options?.replyToId, options?.replyToSenderJid);\n }\n\n /**\n * Send / Remove an E2EE reaction\n *\n * @param chatJid - Chat JID\n * @param messageId - Message ID\n * @param senderJid - Sender JID\n * @param emoji - Reaction emoji (To remove it, simply omit this parameter)\n */\n async sendE2EEReaction(chatJid: string, messageId: string, senderJid: string, emoji?: string): Promise<void> {\n if (!this.handle) throw new Error(\"Not connected\");\n await native.sendE2EEReaction(this.handle, chatJid, messageId, senderJid, emoji || \"\");\n }\n\n /**\n * Send E2EE typing indicator\n *\n * @param chatJid - Chat JID\n * @param isTyping - Whether typing\n */\n async sendE2EETyping(chatJid: string, isTyping: boolean = true): Promise<void> {\n if (!this.handle) throw new Error(\"Not connected\");\n await native.sendE2EETyping(this.handle, chatJid, isTyping);\n }\n\n /**\n * Edit an E2EE message\n *\n * @param chatJid - Chat JID\n * @param messageId - Message ID to edit\n * @param newText - New message text\n */\n async editE2EEMessage(chatJid: string, messageId: string, newText: string): Promise<void> {\n if (!this.handle) throw new Error(\"Not connected\");\n await native.editE2EEMessage(this.handle, chatJid, messageId, newText);\n }\n\n /**\n * Unsend/delete an E2EE message\n *\n * @param chatJid - Chat JID\n * @param messageId - Message ID to unsend\n */\n async unsendE2EEMessage(chatJid: string, messageId: string): Promise<void> {\n if (!this.handle) throw new Error(\"Not connected\");\n await native.unsendE2EEMessage(this.handle, chatJid, messageId);\n }\n\n // ========== E2EE Media Methods ==========\n\n /**\n * Send an E2EE image\n *\n * @param chatJid - Chat JID\n * @param data - Image data as Buffer\n * @param mimeType - MIME type (e.g., image/jpeg, image/png)\n * @param options - Optional caption, dimensions, and reply options\n */\n async sendE2EEImage(\n chatJid: string,\n data: Buffer,\n mimeType: string = \"image/jpeg\",\n options?: { caption?: string; width?: number; height?: number; replyToId?: string; replyToSenderJid?: string },\n ): Promise<SendMessageResult> {\n if (!this.handle) throw new Error(\"Not connected\");\n return native.sendE2EEImage(this.handle, {\n chatJid,\n data: Array.from(data),\n mimeType,\n caption: options?.caption,\n width: options?.width,\n height: options?.height,\n replyToId: options?.replyToId,\n replyToSenderJid: options?.replyToSenderJid,\n });\n }\n\n /**\n * Send an E2EE video\n *\n * @param chatJid - Chat JID\n * @param data - Video data as Buffer\n * @param mimeType - MIME type (default: video/mp4)\n * @param options - Optional caption, dimensions, duration, and reply options\n */\n async sendE2EEVideo(\n chatJid: string,\n data: Buffer,\n mimeType: string = \"video/mp4\",\n options?: {\n caption?: string;\n width?: number;\n height?: number;\n duration?: number;\n replyToId?: string;\n replyToSenderJid?: string;\n },\n ): Promise<SendMessageResult> {\n if (!this.handle) throw new Error(\"Not connected\");\n return native.sendE2EEVideo(this.handle, {\n chatJid,\n data: Array.from(data),\n mimeType,\n caption: options?.caption,\n width: options?.width,\n height: options?.height,\n duration: options?.duration,\n replyToId: options?.replyToId,\n replyToSenderJid: options?.replyToSenderJid,\n });\n }\n\n /**\n * Send an E2EE audio/voice message\n *\n * @param chatJid - Chat JID\n * @param data - Audio data as Buffer\n * @param mimeType - MIME type (default: audio/ogg)\n * @param options - Optional PTT (push-to-talk/voice message), duration, and reply options\n */\n async sendE2EEAudio(\n chatJid: string,\n data: Buffer,\n mimeType: string = \"audio/ogg\",\n options?: { ptt?: boolean; duration?: number; replyToId?: string; replyToSenderJid?: string },\n ): Promise<SendMessageResult> {\n if (!this.handle) throw new Error(\"Not connected\");\n return native.sendE2EEAudio(this.handle, {\n chatJid,\n data: Array.from(data),\n mimeType,\n ptt: options?.ptt ?? false,\n duration: options?.duration,\n replyToId: options?.replyToId,\n replyToSenderJid: options?.replyToSenderJid,\n });\n }\n\n /**\n * Send an E2EE document/file\n *\n * @param chatJid - Chat JID\n * @param data - File data as Buffer\n * @param filename - Filename\n * @param mimeType - MIME type\n * @param options - Optional reply options\n */\n async sendE2EEDocument(\n chatJid: string,\n data: Buffer,\n filename: string,\n mimeType: string,\n options?: { replyToId?: string; replyToSenderJid?: string },\n ): Promise<SendMessageResult> {\n if (!this.handle) throw new Error(\"Not connected\");\n return native.sendE2EEDocument(this.handle, {\n chatJid,\n data: Array.from(data),\n filename,\n mimeType,\n replyToId: options?.replyToId,\n replyToSenderJid: options?.replyToSenderJid,\n });\n }\n\n /**\n * Send an E2EE sticker\n *\n * @param chatJid - Chat JID\n * @param data - Sticker data as Buffer (WebP format)\n * @param mimeType - MIME type (default: image/webp)\n * @param options - Optional reply options\n */\n async sendE2EESticker(\n chatJid: string,\n data: Buffer,\n mimeType: string = \"image/webp\",\n options?: { replyToId?: string; replyToSenderJid?: string },\n ): Promise<SendMessageResult> {\n if (!this.handle) throw new Error(\"Not connected\");\n return native.sendE2EESticker(this.handle, {\n chatJid,\n data: Array.from(data),\n mimeType,\n replyToId: options?.replyToId,\n replyToSenderJid: options?.replyToSenderJid,\n });\n }\n\n /**\n * Get E2EE device data as JSON string\n *\n * Use this to persist device data externally (e.g., in a database)\n *\n * @returns Device data as JSON string\n */\n getDeviceData(): string {\n if (!this.handle) throw new Error(\"Not connected\");\n const result = native.getDeviceData(this.handle);\n return result.deviceData;\n }\n\n private startEventLoop(): void {\n if (this.eventLoopRunning) return;\n this.eventLoopRunning = true;\n this.eventLoopAbort = new AbortController();\n\n const loop = async () => {\n while (this.eventLoopRunning && this.handle) {\n try {\n // Yield to event loop before polling to allow other operations\n await new Promise(resolve => setImmediate(resolve));\n\n const event = (await native.pollEvents(this.handle, 1000)) as ClientEvent;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (!event || (event as any).type === \"timeout\") continue;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((event as any).type === \"closed\") {\n this.eventLoopRunning = false;\n break;\n }\n this.handleEvent(event);\n } catch (err) {\n if (this.eventLoopRunning) {\n this.emit(\"error\", err as Error);\n }\n }\n }\n };\n\n // background task\n setImmediate(loop).unref();\n }\n\n private stopEventLoop(): void {\n this.eventLoopRunning = false;\n this.eventLoopAbort?.abort();\n this.eventLoopAbort = null;\n }\n\n private checkFullyReady(): void {\n if (this.isFullyReady && !this._fullyReadyEmitted) {\n this._fullyReadyEmitted = true;\n this.emit(\"fullyReady\");\n // flush pending events\n const pending = this.pendingEvents;\n this.pendingEvents = [];\n for (const event of pending) {\n this.emitEvent(event);\n }\n }\n }\n\n private handleEvent(event: ClientEvent): void {\n switch (event.type) {\n // System events\n case \"ready\":\n this._socketReady = true;\n this.emit(\"ready\", event.data);\n this.checkFullyReady();\n break;\n case \"reconnected\":\n this.emit(\"reconnected\");\n break;\n case \"disconnected\":\n this._socketReady = false;\n this._e2eeConnected = false;\n this._fullyReadyEmitted = false;\n this.pendingEvents = [];\n this.emit(\"disconnected\", event.data || {});\n break;\n case \"error\":\n this.emit(\"error\", new Error(event.data.message));\n break;\n case \"e2eeConnected\":\n this._e2eeConnected = true;\n this.emit(\"e2eeConnected\");\n this.checkFullyReady();\n break;\n case \"deviceDataChanged\":\n this.emit(\"deviceDataChanged\", event.data);\n break;\n\n // queue until fullyReady\n case \"message\":\n case \"messageEdit\":\n case \"messageUnsend\":\n case \"reaction\":\n case \"typing\":\n case \"readReceipt\":\n case \"e2eeMessage\":\n case \"e2eeReaction\":\n case \"e2eeReceipt\":\n if (this._fullyReadyEmitted) {\n this.emitEvent(event);\n } else {\n this.pendingEvents.push(event);\n }\n break;\n }\n }\n\n private emitEvent(event: ClientEvent): void {\n switch (event.type) {\n case \"message\":\n this.emit(\"message\", event.data);\n break;\n case \"messageEdit\":\n this.emit(\"messageEdit\", event.data);\n break;\n case \"messageUnsend\":\n this.emit(\"messageUnsend\", event.data);\n break;\n case \"reaction\":\n this.emit(\"reaction\", event.data);\n break;\n case \"typing\":\n this.emit(\"typing\", event.data);\n break;\n case \"readReceipt\":\n this.emit(\"readReceipt\", event.data);\n break;\n case \"e2eeMessage\":\n this.emit(\"e2eeMessage\", event.data);\n break;\n case \"e2eeReaction\":\n this.emit(\"e2eeReaction\", event.data);\n break;\n case \"e2eeReceipt\":\n this.emit(\"e2eeReceipt\", event.data);\n break;\n }\n }\n\n /**\n * Unload the native library (for cleanup)\n * @warn Any attempt to find or call a function from this library after unloading it will crash.\n * @returns void\n */\n public unloadLibrary(): void {\n if (this.handle) {\n native.unload();\n }\n }\n}\n","/*\n * meta-messenger.js, Unofficial Meta Messenger Chat API for NodeJS\n * Copyright (c) 2026 Elysia and contributors\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport koffi from \"koffi\";\n\nfunction resolveDirname(): string {\n return path.dirname(fileURLToPath(import.meta.url));\n}\n\nfunction libPath(): string {\n const base = path.join(resolveDirname(), \"..\", \"build\");\n if (process.platform === \"win32\") return path.join(base, \"messagix.dll\");\n if (process.platform === \"darwin\") return path.join(base, \"messagix.dylib\");\n return path.join(base, \"messagix.so\");\n}\n\nconst LIB_FILE = libPath();\nif (!fs.existsSync(LIB_FILE)) {\n throw new Error(`Native library not found at ${LIB_FILE}. Run: npm run build:go`);\n}\n\nconst lib = koffi.load(LIB_FILE);\n\nconst mk = (ret: string, name: string, args: string[]) => lib.func(name, ret, args);\n\nconst fns = {\n MxFreeCString: mk(\"void\", \"MxFreeCString\", [\"char*\"]),\n MxNewClient: mk(\"str\", \"MxNewClient\", [\"str\"]),\n MxConnect: mk(\"str\", \"MxConnect\", [\"str\"]),\n MxConnectE2EE: mk(\"str\", \"MxConnectE2EE\", [\"str\"]),\n MxDisconnect: mk(\"str\", \"MxDisconnect\", [\"str\"]),\n MxIsConnected: mk(\"str\", \"MxIsConnected\", [\"str\"]),\n MxSendMessage: mk(\"str\", \"MxSendMessage\", [\"str\"]),\n MxSendReaction: mk(\"str\", \"MxSendReaction\", [\"str\"]),\n MxEditMessage: mk(\"str\", \"MxEditMessage\", [\"str\"]),\n MxUnsendMessage: mk(\"str\", \"MxUnsendMessage\", [\"str\"]),\n MxSendTyping: mk(\"str\", \"MxSendTyping\", [\"str\"]),\n MxMarkRead: mk(\"str\", \"MxMarkRead\", [\"str\"]),\n MxUploadMedia: mk(\"str\", \"MxUploadMedia\", [\"str\"]),\n MxSendImage: mk(\"str\", \"MxSendImage\", [\"str\"]),\n MxSendVideo: mk(\"str\", \"MxSendVideo\", [\"str\"]),\n MxSendVoice: mk(\"str\", \"MxSendVoice\", [\"str\"]),\n MxSendFile: mk(\"str\", \"MxSendFile\", [\"str\"]),\n MxSendSticker: mk(\"str\", \"MxSendSticker\", [\"str\"]),\n MxCreateThread: mk(\"str\", \"MxCreateThread\", [\"str\"]),\n MxGetUserInfo: mk(\"str\", \"MxGetUserInfo\", [\"str\"]),\n MxSetGroupPhoto: mk(\"str\", \"MxSetGroupPhoto\", [\"str\"]),\n MxRenameThread: mk(\"str\", \"MxRenameThread\", [\"str\"]),\n MxMuteThread: mk(\"str\", \"MxMuteThread\", [\"str\"]),\n MxDeleteThread: mk(\"str\", \"MxDeleteThread\", [\"str\"]),\n MxSearchUsers: mk(\"str\", \"MxSearchUsers\", [\"str\"]),\n MxPollEvents: mk(\"str\", \"MxPollEvents\", [\"str\"]),\n MxSendE2EEMessage: mk(\"str\", \"MxSendE2EEMessage\", [\"str\"]),\n MxSendE2EEReaction: mk(\"str\", \"MxSendE2EEReaction\", [\"str\"]),\n MxSendE2EETyping: mk(\"str\", \"MxSendE2EETyping\", [\"str\"]),\n MxEditE2EEMessage: mk(\"str\", \"MxEditE2EEMessage\", [\"str\"]),\n MxUnsendE2EEMessage: mk(\"str\", \"MxUnsendE2EEMessage\", [\"str\"]),\n MxGetDeviceData: mk(\"str\", \"MxGetDeviceData\", [\"str\"]),\n // E2EE Media functions\n MxSendE2EEImage: mk(\"str\", \"MxSendE2EEImage\", [\"str\"]),\n MxSendE2EEVideo: mk(\"str\", \"MxSendE2EEVideo\", [\"str\"]),\n MxSendE2EEAudio: mk(\"str\", \"MxSendE2EEAudio\", [\"str\"]),\n MxSendE2EEDocument: mk(\"str\", \"MxSendE2EEDocument\", [\"str\"]),\n MxSendE2EESticker: mk(\"str\", \"MxSendE2EESticker\", [\"str\"]),\n} as const;\n\ninterface JsonResp<T = unknown> {\n ok: boolean;\n data?: T;\n error?: string;\n}\n\nfunction call<T>(fn: keyof typeof fns, payload: unknown): T {\n const input = JSON.stringify(payload);\n const bound = fns[fn] as (arg: string) => string;\n const out = bound(input);\n const data = JSON.parse(out) as JsonResp<T>;\n if (!data.ok) throw new Error(data.error || \"Unknown error\");\n return data.data as T;\n}\n\n// Async version that yields to event loop\nfunction callAsync<T>(fn: keyof typeof fns, payload: unknown): Promise<T> {\n return new Promise((resolve, reject) => {\n // Use setTimeout(0) to yield to event loop\n setTimeout(() => {\n try {\n const result = call<T>(fn, payload);\n resolve(result);\n } catch (err) {\n reject(err);\n }\n }, 0);\n });\n}\n\nexport const native = {\n newClient: (cfg: {\n cookies: Record<string, string>;\n platform?: string;\n devicePath?: string;\n deviceData?: string;\n logLevel?: string;\n }) => call<{ handle: number }>(\"MxNewClient\", cfg),\n\n connect: (handle: number) =>\n call<{\n user: { id: number; name: string; username: string };\n initialData: { threads: unknown[]; messages: unknown[] };\n }>(\"MxConnect\", { handle }),\n\n connectE2EE: (handle: number) => callAsync<unknown>(\"MxConnectE2EE\", { handle }),\n\n disconnect: (handle: number) => call<unknown>(\"MxDisconnect\", { handle }),\n\n isConnected: (handle: number) => call<{ connected: boolean; e2eeConnected: boolean }>(\"MxIsConnected\", { handle }),\n\n sendMessage: (\n handle: number,\n options: {\n threadId: number;\n text: string;\n replyToId?: string;\n mentionIds?: number[];\n mentionOffsets?: number[];\n mentionLengths?: number[];\n attachmentFbIds?: number[];\n stickerId?: number;\n url?: string;\n isE2EE?: boolean;\n e2eeChatJid?: string;\n },\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendMessage\", { handle, options }),\n\n sendReaction: (handle: number, threadId: number, messageId: string, emoji: string) =>\n callAsync<unknown>(\"MxSendReaction\", { handle, threadId, messageId, emoji }),\n\n editMessage: (handle: number, messageId: string, newText: string) =>\n callAsync<unknown>(\"MxEditMessage\", { handle, messageId, newText }),\n\n unsendMessage: (handle: number, messageId: string) => callAsync<unknown>(\"MxUnsendMessage\", { handle, messageId }),\n\n sendTyping: (handle: number, threadId: number, isTyping: boolean, isGroup: boolean, threadType: number) =>\n callAsync<unknown>(\"MxSendTyping\", { handle, threadId, isTyping, isGroup, threadType }),\n\n markRead: (handle: number, threadId: number, watermarkTs?: number) =>\n callAsync<unknown>(\"MxMarkRead\", { handle, threadId, watermarkTs: watermarkTs || 0 }),\n\n uploadMedia: (\n handle: number,\n options: {\n threadId: number;\n filename: string;\n mimeType: string;\n data: number[];\n isVoice?: boolean;\n },\n ) => callAsync<{ fbId: number; filename: string }>(\"MxUploadMedia\", { handle, options }),\n\n sendImage: (handle: number, options: { threadId: number; data: number[]; filename: string; caption?: string }) =>\n callAsync<{ messageId: string; timestampMs: number }>(\"MxSendImage\", { handle, options }),\n\n sendVideo: (handle: number, options: { threadId: number; data: number[]; filename: string; caption?: string }) =>\n callAsync<{ messageId: string; timestampMs: number }>(\"MxSendVideo\", { handle, options }),\n\n sendVoice: (handle: number, options: { threadId: number; data: number[]; filename: string }) =>\n callAsync<{ messageId: string; timestampMs: number }>(\"MxSendVoice\", { handle, options }),\n\n sendFile: (\n handle: number,\n options: {\n threadId: number;\n data: number[];\n filename: string;\n mimeType: string;\n caption?: string;\n },\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendFile\", { handle, options }),\n\n sendSticker: (handle: number, options: { threadId: number; stickerId: number }) =>\n callAsync<{ messageId: string; timestampMs: number }>(\"MxSendSticker\", { handle, options }),\n\n createThread: (handle: number, options: { userId: number }) =>\n callAsync<{ threadId: number }>(\"MxCreateThread\", { handle, options }),\n\n getUserInfo: (handle: number, options: { userId: number }) =>\n callAsync<{\n id: number;\n name: string;\n firstName?: string;\n username?: string;\n profilePictureUrl?: string;\n isMessengerUser?: boolean;\n isVerified?: boolean;\n gender?: number;\n canViewerMessage?: boolean;\n }>(\"MxGetUserInfo\", { handle, options }),\n\n setGroupPhoto: (handle: number, threadId: number, data: string, mimeType: string) =>\n callAsync<unknown>(\"MxSetGroupPhoto\", { handle, threadId, data, mimeType }),\n\n renameThread: (handle: number, options: { threadId: number; newName: string }) =>\n callAsync<unknown>(\"MxRenameThread\", { handle, options }),\n\n muteThread: (handle: number, options: { threadId: number; muteSeconds: number }) =>\n callAsync<unknown>(\"MxMuteThread\", { handle, options }),\n\n deleteThread: (handle: number, options: { threadId: number }) =>\n callAsync<unknown>(\"MxDeleteThread\", { handle, options }),\n\n searchUsers: (handle: number, options: { query: string }) =>\n callAsync<{ users: { id: number; name: string; username: string }[] }>(\"MxSearchUsers\", {\n handle,\n options,\n }),\n\n pollEvents: (handle: number, timeoutMs: number) => callAsync<unknown>(\"MxPollEvents\", { handle, timeoutMs }),\n\n // E2EE functions\n sendE2EEMessage: (handle: number, chatJid: string, text: string, replyToId?: string, replyToSenderJid?: string) =>\n callAsync<{ messageId: string; timestampMs: number }>(\"MxSendE2EEMessage\", {\n handle,\n chatJid,\n text,\n replyToId,\n replyToSenderJid,\n }),\n\n sendE2EEReaction: (handle: number, chatJid: string, messageId: string, senderJid: string, emoji: string) =>\n callAsync<unknown>(\"MxSendE2EEReaction\", { handle, chatJid, messageId, senderJid, emoji }),\n\n sendE2EETyping: (handle: number, chatJid: string, isTyping: boolean) =>\n callAsync<unknown>(\"MxSendE2EETyping\", { handle, chatJid, isTyping }),\n\n editE2EEMessage: (handle: number, chatJid: string, messageId: string, newText: string) =>\n callAsync<unknown>(\"MxEditE2EEMessage\", { handle, chatJid, messageId, newText }),\n\n unsendE2EEMessage: (handle: number, chatJid: string, messageId: string) =>\n callAsync<unknown>(\"MxUnsendE2EEMessage\", { handle, chatJid, messageId }),\n\n getDeviceData: (handle: number) => call<{ deviceData: string }>(\"MxGetDeviceData\", { handle }),\n\n // E2EE Media functions\n sendE2EEImage: (\n handle: number,\n options: {\n chatJid: string;\n data: number[];\n mimeType: string;\n caption?: string;\n width?: number;\n height?: number;\n replyToId?: string;\n replyToSenderJid?: string;\n },\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendE2EEImage\", { handle, options }),\n\n sendE2EEVideo: (\n handle: number,\n options: {\n chatJid: string;\n data: number[];\n mimeType: string;\n caption?: string;\n width?: number;\n height?: number;\n duration?: number;\n replyToId?: string;\n replyToSenderJid?: string;\n },\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendE2EEVideo\", { handle, options }),\n\n sendE2EEAudio: (\n handle: number,\n options: {\n chatJid: string;\n data: number[];\n mimeType: string;\n duration?: number;\n ptt?: boolean; // Push-to-talk (voice message)\n replyToId?: string;\n replyToSenderJid?: string;\n },\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendE2EEAudio\", { handle, options }),\n\n sendE2EEDocument: (\n handle: number,\n options: {\n chatJid: string;\n data: number[];\n filename: string;\n mimeType: string;\n replyToId?: string;\n replyToSenderJid?: string;\n },\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendE2EEDocument\", { handle, options }),\n\n sendE2EESticker: (\n handle: number,\n options: {\n chatJid: string;\n data: number[];\n mimeType: string;\n replyToId?: string;\n replyToSenderJid?: string;\n },\n ) => callAsync<{ messageId: string; timestampMs: number }>(\"MxSendE2EESticker\", { handle, options }),\n\n unload: () => lib.unload(),\n};\n","/*\n * meta-messenger.js, Unofficial Meta Messenger Chat API for NodeJS\n * Copyright (c) 2026 Elysia and contributors\n */\n\n/**\n * Event types emitted by the client\n */\nexport type EventType =\n | \"ready\"\n | \"reconnected\"\n | \"disconnected\"\n | \"error\"\n | \"message\"\n | \"messageEdit\"\n | \"messageUnsend\"\n | \"reaction\"\n | \"typing\"\n | \"readReceipt\"\n | \"e2eeConnected\"\n | \"e2eeMessage\"\n | \"e2eeReaction\"\n | \"e2eeReceipt\"\n | \"deviceDataChanged\";\n\n/**\n * Base event interface\n */\nexport interface BaseEvent {\n type: EventType;\n timestamp: number;\n}\n\n/**\n * Ready event - emitted when connected to Messenger\n */\nexport interface ReadyEvent extends BaseEvent {\n type: \"ready\";\n data: {\n isNewSession: boolean;\n };\n}\n\n/**\n * Reconnected event\n */\nexport interface ReconnectedEvent extends BaseEvent {\n type: \"reconnected\";\n}\n\n/**\n * Disconnected event\n */\nexport interface DisconnectedEvent extends BaseEvent {\n type: \"disconnected\";\n data?: {\n isE2EE?: boolean;\n };\n}\n\n/**\n * Error event\n */\nexport interface ErrorEvent extends BaseEvent {\n type: \"error\";\n data: {\n message: string;\n code?: number;\n };\n}\n\n/**\n * Message event - new message received\n */\nexport interface MessageEvent extends BaseEvent {\n type: \"message\";\n data: Message;\n}\n\n/**\n * Message edit event\n */\nexport interface MessageEditEvent extends BaseEvent {\n type: \"messageEdit\";\n data: {\n messageId: string;\n threadId: number;\n newText: string;\n editCount?: number;\n timestampMs?: number;\n };\n}\n\n/**\n * Message unsend event\n */\nexport interface MessageUnsendEvent extends BaseEvent {\n type: \"messageUnsend\";\n data: {\n messageId: string;\n threadId: number;\n };\n}\n\n/**\n * Reaction event\n */\nexport interface ReactionEvent extends BaseEvent {\n type: \"reaction\";\n data: {\n messageId: string;\n threadId: number;\n actorId: number;\n reaction: string;\n timestampMs: number;\n };\n}\n\n/**\n * Typing event\n */\nexport interface TypingEvent extends BaseEvent {\n type: \"typing\";\n data: {\n threadId: number;\n senderId: number;\n isTyping: boolean;\n };\n}\n\n/**\n * Read receipt event\n */\nexport interface ReadReceiptEvent extends BaseEvent {\n type: \"readReceipt\";\n data: {\n threadId: number;\n readerId: number;\n readWatermarkTimestampMs: number;\n timestampMs?: number;\n };\n}\n\n/**\n * E2EE connected event\n */\nexport interface E2EEConnectedEvent extends BaseEvent {\n type: \"e2eeConnected\";\n}\n\n/**\n * E2EE message event\n */\nexport interface E2EEMessageEvent extends BaseEvent {\n type: \"e2eeMessage\";\n data: E2EEMessage;\n}\n\n/**\n * E2EE reaction event\n */\nexport interface E2EEReactionEvent extends BaseEvent {\n type: \"e2eeReaction\";\n data: {\n messageId: string;\n chatJid: string;\n senderJid: string;\n reaction: string;\n };\n}\n\n/**\n * E2EE receipt event\n */\nexport interface E2EEReceiptEvent extends BaseEvent {\n type: \"e2eeReceipt\";\n data: {\n type: string;\n chat: string;\n sender: string;\n messageIds: string[];\n };\n}\n\n/**\n * Device data changed event - emitted when E2EE device data changes (only when using deviceData option)\n */\nexport interface DeviceDataChangedEvent extends BaseEvent {\n type: \"deviceDataChanged\";\n data: {\n deviceData: string;\n };\n}\n\n/**\n * Union of all events\n */\nexport type ClientEvent =\n | ReadyEvent\n | ReconnectedEvent\n | DisconnectedEvent\n | ErrorEvent\n | MessageEvent\n | MessageEditEvent\n | MessageUnsendEvent\n | ReactionEvent\n | TypingEvent\n | ReadReceiptEvent\n | E2EEConnectedEvent\n | E2EEMessageEvent\n | E2EEReactionEvent\n | E2EEReceiptEvent\n | DeviceDataChangedEvent;\n\n/**\n * User information\n */\nexport interface User {\n id: number;\n name: string;\n username: string;\n}\n\n/**\n * Thread/conversation\n */\nexport interface Thread {\n id: number;\n type: ThreadType;\n name: string;\n lastActivityTimestampMs: number;\n snippet: string;\n}\n\n/**\n * Thread types\n */\nexport enum ThreadType {\n ONE_TO_ONE = 1,\n GROUP = 2,\n PAGE = 3,\n MARKETPLACE = 4,\n ENCRYPTED_ONE_TO_ONE = 7,\n ENCRYPTED_GROUP = 8,\n}\n\n/**\n * Attachment type\n */\nexport type AttachmentType = \"image\" | \"video\" | \"audio\" | \"file\" | \"sticker\" | \"gif\" | \"voice\" | \"location\" | \"link\";\n\n/**\n * Media attachment\n */\nexport interface Attachment {\n type: AttachmentType;\n url?: string;\n fileName?: string;\n mimeType?: string;\n fileSize?: number;\n width?: number;\n height?: number;\n duration?: number; // in seconds for audio/video\n stickerId?: number;\n latitude?: number;\n longitude?: number;\n previewUrl?: string;\n // For E2EE media download\n mediaKey?: string; // base64 encoded\n mediaSha256?: string; // base64 encoded\n directPath?: string;\n}\n\n/**\n * Reply info\n */\nexport interface ReplyTo {\n messageId: string;\n senderId?: number;\n text?: string;\n}\n\n/**\n * Mention in message\n */\nexport interface Mention {\n userId: number;\n offset: number;\n length: number;\n type?: \"user\" | \"page\" | \"group\";\n}\n\n/**\n * Message\n */\nexport interface Message {\n id: string;\n threadId: number;\n senderId: number;\n text: string;\n timestampMs: number;\n isE2EE?: boolean;\n chatJid?: string;\n senderJid?: string;\n attachments?: Attachment[];\n replyTo?: ReplyTo;\n mentions?: Mention[];\n isAdminMsg?: boolean;\n}\n\n/**\n * E2EE Message\n */\nexport interface E2EEMessage {\n id: string;\n threadId: number;\n chatJid: string;\n senderJid: string;\n senderId: number;\n text: string;\n timestampMs: number;\n attachments?: Attachment[];\n replyTo?: ReplyTo;\n mentions?: Mention[];\n}\n\n/**\n * Read receipt event data\n */\nexport interface ReadReceiptData {\n threadId: number;\n readerId: number;\n readWatermarkTimestampMs: number;\n timestampMs?: number;\n}\n\n/**\n * Initial data received on connect\n */\nexport interface InitialData {\n threads: Thread[];\n messages: Message[];\n}\n\n/**\n * Platform type\n */\nexport type Platform = \"facebook\" | \"messenger\" | \"instagram\";\n\n/**\n * Log level\n */\nexport type LogLevel = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"none\";\n\n/**\n * Cookies required for authentication\n */\nexport interface Cookies {\n c_user: string;\n xs: string;\n datr?: string;\n fr?: string;\n [key: string]: string | undefined;\n}\n\n/**\n * Client options\n */\nexport interface ClientOptions {\n /** Platform to connect to (Only tested on Facebook) */\n platform?: Platform;\n /** Path to E2EE device store (if not using deviceData) */\n devicePath?: string;\n /** E2EE device data as JSON string (takes priority over devicePath) */\n deviceData?: string;\n /** Log level */\n logLevel?: LogLevel;\n /** Enable E2EE */\n enableE2EE?: boolean;\n /** Auto reconnect on disconnect */\n autoReconnect?: boolean;\n}\n\n/**\n * Send message options\n */\nexport interface SendMessageOptions {\n /** Text content */\n text: string;\n /** Reply to message ID */\n replyToId?: string;\n /** User IDs to mention */\n mentions?: Array<{\n userId: number;\n offset: number;\n length: number;\n }>;\n}\n\n/**\n * Send message result\n */\nexport interface SendMessageResult {\n messageId: string;\n timestampMs: number;\n}\n\n/**\n * Upload media result\n */\nexport interface UploadMediaResult {\n fbId: number;\n filename: string;\n}\n\n/**\n * Search user result\n */\nexport interface SearchUserResult {\n id: number;\n name: string;\n username: string;\n}\n\n/**\n * Create thread result (1:1 chat)\n */\nexport interface CreateThreadResult {\n threadId: number;\n}\n\n/**\n * User information\n */\nexport interface UserInfo {\n id: number;\n name: string;\n firstName?: string;\n username?: string;\n profilePictureUrl?: string;\n isMessengerUser?: boolean;\n isVerified?: boolean;\n gender?: number;\n canViewerMessage?: boolean;\n}\n","/*\n * meta-messenger.js, Unofficial Meta Messenger Chat API for NodeJS\n * Copyright (c) 2026 Elysia and contributors\n */\n\n/**\n * Utility class for cookie parsing and conversion\n *\n * Supports multiple cookie formats:\n * - C3C UFC Utility / EditThisCookie (array of cookie objects)\n * - Simple object format { name: value }\n * - Netscape/HTTP cookie file format\n * - Cookie header string format\n * - Base64 encoded cookies\n */\n\nimport type { Cookies } from \"./types.js\";\n\n/**\n * Cookie object format (C3C UFC Utility / EditThisCookie style)\n */\nexport interface CookieObject {\n name: string;\n value: string;\n domain?: string;\n path?: string;\n expires?: number | string;\n expirationDate?: number;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: string;\n hostOnly?: boolean;\n session?: boolean;\n}\n\n/**\n * Netscape cookie file line format\n */\nexport interface NetscapeCookie {\n domain: string;\n flag: boolean;\n path: string;\n secure: boolean;\n expiration: number;\n name: string;\n value: string;\n}\n\n/**\n * Static utility class for cookie operations\n * @example\n * ```typescript\n * import { Utils } from 'meta-messenger.js'\n *\n * // Parse any cookie format\n * const cookies = Utils.parseCookies(rawData)\n *\n * // Convert cookies to header string\n * const header = Utils.toCookieString(cookies)\n * ```\n */\nexport class Utils extends null {\n /**\n * Parse cookies from various formats\n * Automatically detects the format and parses accordingly\n *\n * @param input - Cookie data in any supported format\n * @returns Parsed cookies object\n */\n static parseCookies(input: string | CookieObject[] | Record<string, string>): Cookies {\n // Already a simple object\n if (typeof input === \"object\" && !Array.isArray(input)) {\n return input as Cookies;\n }\n\n // Array of cookie objects (C3C UFC Utility / EditThisCookie)\n if (Array.isArray(input)) {\n return Utils.fromCookieArray(input);\n }\n\n // String input - detect format\n if (typeof input === \"string\") {\n const trimmed = input.trim();\n\n // Try Base64 first\n if (Utils.isBase64(trimmed)) {\n try {\n const decoded = Buffer.from(trimmed, \"base64\").toString(\"utf-8\");\n return Utils.parseCookies(decoded);\n } catch {\n // Not valid base64, continue with other formats\n }\n }\n\n // Try JSON (array or object)\n if (trimmed.startsWith(\"[\") || trimmed.startsWith(\"{\")) {\n try {\n const parsed = JSON.parse(trimmed);\n return Utils.parseCookies(parsed);\n } catch {\n // Not valid JSON, continue with other formats\n }\n }\n\n // Netscape cookie file format (starts with # or domain)\n if (\n trimmed.includes(\"\\t\") &&\n (trimmed.startsWith(\"#\") || trimmed.includes(\".facebook.com\") || trimmed.includes(\".messenger.com\"))\n ) {\n return Utils.fromNetscape(trimmed);\n }\n\n // Cookie header string format (name=value; name2=value2)\n if (trimmed.includes(\"=\")) {\n return Utils.fromCookieString(trimmed);\n }\n }\n\n throw new Error(\"Unable to parse cookies: unknown format\");\n }\n\n /**\n * Parse cookies from C3C UFC Utility / EditThisCookie array format\n *\n * @param cookies - Array of cookie objects\n * @returns Parsed cookies object\n *\n * @example\n * ```typescript\n * const cookies = Utils.fromCookieArray([\n * { name: 'c_user', value: '123456' },\n * { name: 'xs', value: 'abc...' }\n * ])\n * ```\n */\n static fromCookieArray(cookies: CookieObject[]): Cookies {\n const result: Record<string, string> = {};\n for (const cookie of cookies) {\n if (cookie.name && cookie.value !== undefined) {\n result[cookie.name] = String(cookie.value);\n }\n }\n return result as Cookies;\n }\n\n /**\n * Parse cookies from cookie header string format\n *\n * @param cookieString - Cookie string (e.g., \"name1=value1; name2=value2\")\n * @returns Parsed cookies object\n *\n * @example\n * ```typescript\n * const cookies = Utils.fromCookieString('c_user=123456; xs=abc...; datr=xyz...')\n * ```\n */\n static fromCookieString(cookieString: string): Cookies {\n const result: Record<string, string> = {};\n const pairs = cookieString.split(/;\\s*/);\n\n for (const pair of pairs) {\n const [name, ...valueParts] = pair.split(\"=\");\n if (name && valueParts.length > 0) {\n const trimmedName = name.trim();\n const value = valueParts.join(\"=\").trim();\n if (trimmedName && value) {\n result[trimmedName] = value;\n }\n }\n }\n\n return result as Cookies;\n }\n\n /**\n * Parse cookies from Netscape/HTTP cookie file format\n *\n * @param content - Netscape cookie file content\n * @returns Parsed cookies object\n *\n * @example\n * ```typescript\n * const cookies = Utils.fromNetscape(`\n * # Netscape HTTP Cookie File\n * .facebook.com\tTRUE\t/\tTRUE\t1234567890\tc_user\t123456\n * .facebook.com\tTRUE\t/\tTRUE\t1234567890\txs\tabc...\n * `)\n * ```\n */\n static fromNetscape(content: string): Cookies {\n const result: Record<string, string> = {};\n const lines = content.split(\"\\n\");\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip comments and empty lines\n if (!trimmed || trimmed.startsWith(\"#\")) {\n continue;\n }\n\n // Parse tab-separated values\n const parts = trimmed.split(\"\\t\");\n if (parts.length >= 7) {\n const name = parts[5];\n const value = parts[6];\n if (name && value) {\n result[name] = value;\n }\n }\n }\n\n return result as Cookies;\n }\n\n /**\n * Parse cookies from Base64 encoded string\n *\n * @param base64 - Base64 encoded cookie data\n * @returns Parsed cookies object\n */\n static fromBase64(base64: string): Cookies {\n const decoded = Buffer.from(base64, \"base64\").toString(\"utf-8\");\n return Utils.parseCookies(decoded);\n }\n\n /**\n * Convert cookies object to cookie header string\n *\n * @param cookies - Cookies object\n * @returns Cookie header string\n *\n * @example\n * ```typescript\n * const header = Utils.toCookieString({ c_user: '123456', xs: 'abc...' })\n * // Returns: \"c_user=123456; xs=abc...\"\n * ```\n */\n static toCookieString(cookies: Cookies): string {\n return Object.entries(cookies)\n .map(([name, value]) => `${name}=${value}`)\n .join(\"; \");\n }\n\n /**\n * Convert cookies object to array format (C3C UFC Utility style)\n *\n * @param cookies - Cookies object\n * @param domain - Cookie domain (default: .facebook.com)\n * @returns Array of cookie objects\n *\n * @example\n * ```typescript\n * const arr = Utils.toCookieArray({ c_user: '123456', xs: 'abc...' })\n * ```\n */\n static toCookieArray(cookies: Cookies, domain = \".facebook.com\"): CookieObject[] {\n return Object.entries(cookies)\n .filter(([, value]) => value !== undefined)\n .map(([name, value]) => ({\n name,\n value: value as string,\n domain,\n path: \"/\",\n secure: true,\n httpOnly: true,\n }));\n }\n\n /**\n * Convert cookies object to Netscape format\n *\n * @param cookies - Cookies object\n * @param domain - Cookie domain (default: .facebook.com)\n * @returns Netscape cookie file content\n */\n static toNetscape(cookies: Cookies, domain = \".facebook.com\"): string {\n const lines = [\"# Netscape HTTP Cookie File\", \"# Generated by meta-messenger.js\", \"\"];\n\n for (const [name, value] of Object.entries(cookies)) {\n // domain, flag, path, secure, expiration, name, value\n const expiration = Math.floor(Date.now() / 1000) + 365 * 24 * 60 * 60; // 1 year\n lines.push(`${domain}\\tTRUE\\t/\\tTRUE\\t${expiration}\\t${name}\\t${value}`);\n }\n\n return lines.join(\"\\n\");\n }\n\n /**\n * Convert cookies to Base64 encoded JSON\n *\n * @param cookies - Cookies object\n * @returns Base64 encoded string\n */\n static toBase64(cookies: Cookies): string {\n return Buffer.from(JSON.stringify(cookies)).toString(\"base64\");\n }\n\n /**\n * Filter cookies to only essential ones for Facebook/Messenger\n *\n * @param cookies - Cookies object\n * @returns Filtered cookies with only essential keys\n */\n static filterEssential(cookies: Cookies): Cookies {\n const essential = [\"c_user\", \"xs\", \"datr\", \"fr\", \"sb\", \"wd\", \"presence\"];\n const result: Record<string, string> = {};\n\n for (const key of essential) {\n if (cookies[key]) {\n result[key] = cookies[key] as string;\n }\n }\n\n return result as Cookies;\n }\n\n /**\n * Validate that cookies contain required fields\n *\n * @param cookies - Cookies object\n * @returns True if cookies are valid\n */\n static validate(cookies: Cookies): boolean {\n const required = [\"c_user\", \"xs\"];\n return required.every(key => cookies[key] && cookies[key].length > 0);\n }\n\n /**\n * Get missing required cookies\n *\n * @param cookies - Cookies object\n * @returns Array of missing cookie names\n */\n static getMissing(cookies: Cookies): string[] {\n const required = [\"c_user\", \"xs\"];\n return required.filter(key => !cookies[key] || cookies[key].length === 0);\n }\n\n /**\n * Check if a string is valid Base64\n */\n private static isBase64(str: string): boolean {\n if (str.length < 4) return false;\n // Check if string contains only valid base64 characters\n const base64Regex = /^[A-Za-z0-9+/]+=*$/;\n if (!base64Regex.test(str)) return false;\n // Try to detect if it's likely base64 (not a simple word)\n return str.length > 20 && str.length % 4 === 0;\n }\n}\n","/*\n * meta-messenger.js, Unofficial Meta Messenger Chat API for NodeJS\n * Copyright (c) 2026 Elysia and contributors\n */\n\n/**\n * meta-messenger.js - TypeScript wrapper for Facebook Messenger with E2EE support\n *\n * @example\n * ```typescript\n * import { Client, login } from 'meta-messenger.js'\n *\n * // Method 1: Using Client class directly\n * const client = new Client({\n * c_user: 'your_user_id',\n * xs: 'your_xs_cookie',\n * datr: 'your_datr_cookie',\n * fr: 'your_fr_cookie'\n * })\n *\n * client.on('message', (message) => {\n * console.log('New message:', message)\n * if (message.text === 'ping') {\n * client.sendMessage(message.threadId, 'pong')\n * }\n * })\n *\n * await client.connect()\n *\n * // Method 2: Using login function (facebook-chat-api style)\n * const api = await login({\n * c_user: 'your_user_id',\n * xs: 'your_xs_cookie',\n * datr: 'your_datr_cookie',\n * fr: 'your_fr_cookie'\n * })\n *\n * api.on('message', (message) => {\n * console.log('Got message:', message.text)\n * })\n * ```\n *\n * @packageDocumentation\n */\n\nexport type { ClientEventMap } from \"./client.js\";\nexport { Client } from \"./client.js\";\nexport {\n type BaseEvent,\n type ClientEvent,\n type ClientOptions,\n type Cookies,\n type CreateThreadResult,\n type DisconnectedEvent,\n type E2EEConnectedEvent,\n type E2EEMessage,\n type E2EEMessageEvent,\n type E2EEReactionEvent,\n type E2EEReceiptEvent,\n type ErrorEvent,\n // Types\n type EventType,\n type InitialData,\n type LogLevel,\n type Message,\n type MessageEditEvent,\n type MessageEvent,\n type MessageUnsendEvent,\n type Platform,\n type ReactionEvent,\n type ReadyEvent,\n type ReconnectedEvent,\n type SearchUserResult,\n type SendMessageOptions,\n type SendMessageResult,\n type Thread,\n // Enums\n ThreadType,\n type TypingEvent,\n type UploadMediaResult,\n type User,\n type UserInfo,\n} from \"./types.js\";\nexport { type CookieObject, Utils } from \"./utils.js\";\n\nimport { Client } from \"./client.js\";\nimport type { ClientOptions, Cookies } from \"./types.js\";\n\n/**\n * Login to Facebook Messenger (E2EE disabled for simplicity)\n *\n * @param cookies - Authentication cookies\n * @param options - Client options\n * @returns Connected client instance\n *\n * @example\n * ```typescript\n * const api = await login({\n * c_user: 'your_user_id',\n * xs: 'your_xs_cookie',\n * datr: 'your_datr_cookie',\n * fr: 'your_fr_cookie'\n * })\n *\n * console.log('Logged in as:', api.user?.name)\n *\n * api.on('message', async (message) => {\n * if (message.senderId !== api.currentUserId) {\n * await api.sendMessage(message.threadId, 'Hello!')\n * }\n * })\n * ```\n */\nexport async function login(cookies: Cookies, options?: ClientOptions): Promise<Client> {\n const client = new Client(cookies, options);\n await client.connect();\n return client;\n}\n\n/**\n * Create a client without connecting\n *\n * @param cookies - Authentication cookies\n * @param options - Client options\n * @returns Client instance (not connected)\n */\nexport function createClient(cookies: Cookies, options?: ClientOptions): Client {\n return new Client(cookies, options);\n}\n\n// Default export for convenience\nexport default { Client, login, createClient };\n"],"mappings":"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","names":["ThreadType"]}
|
package/package.json
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "meta-messenger.js",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "Unofficial Meta Messenger Chat API for NodeJS",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"scripts": {
|
|
9
|
+
"test": "tsc --noEmit && npm run lint",
|
|
9
10
|
"build:go": "node scripts/build-go.mjs",
|
|
10
11
|
"build:ts": "tsup",
|
|
11
12
|
"build": "npm run build:go && npm run build:ts",
|
|
12
13
|
"postinstall": "node scripts/postinstall.mjs",
|
|
13
14
|
"lint:fix": "eslint . --fix",
|
|
14
15
|
"lint": "eslint .",
|
|
15
|
-
"
|
|
16
|
+
"format:fix": "prettier --write --list-different .",
|
|
17
|
+
"format": "prettier --check ."
|
|
16
18
|
},
|
|
17
19
|
"publishConfig": {
|
|
18
20
|
"access": "public"
|
|
@@ -45,11 +47,12 @@
|
|
|
45
47
|
"eslint-plugin-simple-header": "^1.0.2",
|
|
46
48
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
47
49
|
"eslint-plugin-unused-imports": "^4.0.0",
|
|
50
|
+
"prettier": "^3.8.1",
|
|
48
51
|
"tsup": "^8.5.1",
|
|
49
52
|
"tsx": "^4.21.0",
|
|
50
53
|
"typescript": "^5.9.3"
|
|
51
54
|
},
|
|
52
55
|
"engines": {
|
|
53
|
-
"node": ">=22"
|
|
56
|
+
"node": ">=22.12.0"
|
|
54
57
|
}
|
|
55
58
|
}
|
package/scripts/build-go.mjs
CHANGED
|
@@ -1,30 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
console.log(`[${name}]
|
|
1
|
+
/*
|
|
2
|
+
* meta-messenger.js, Unofficial Meta Messenger Chat API for NodeJS
|
|
3
|
+
* Copyright (c) 2026 Elysia and contributors
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { spawnSync } from "node:child_process";
|
|
7
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
8
|
+
import { dirname, join } from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
|
|
11
|
+
import { detectPlatform } from "./detect-platform.mjs";
|
|
12
|
+
import { packageJson } from "./package.mjs";
|
|
13
|
+
|
|
14
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
const { ext } = detectPlatform();
|
|
16
|
+
const { name } = packageJson;
|
|
17
|
+
|
|
18
|
+
function runGo(args) {
|
|
19
|
+
const res = spawnSync(process.env.GO_BIN || "go", args, {
|
|
20
|
+
cwd: join(__dirname, "..", "bridge-go"),
|
|
21
|
+
stdio: "inherit",
|
|
22
|
+
env: process.env,
|
|
23
|
+
});
|
|
24
|
+
if (res.status !== 0) process.exit(res.status || 1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const buildDir = join(__dirname, "..", "build");
|
|
28
|
+
if (!existsSync(buildDir)) mkdirSync(buildDir, { recursive: true });
|
|
29
|
+
|
|
30
|
+
console.log(`[${name}] Tidying Go modules...`);
|
|
31
|
+
runGo(["mod", "tidy"]);
|
|
32
|
+
|
|
33
|
+
console.log(`[${name}] Building native library (release mode)...`);
|
|
34
|
+
runGo(["build", "-buildmode=c-shared", "-ldflags=-s -w", "-o", join("..", "build", `messagix.${ext}`), "."]);
|
|
35
|
+
|
|
36
|
+
console.log(`[${name}] Built native: build/messagix.${ext}`);
|