@elizaos/plugin-whatsapp 2.0.0-alpha.7 → 2.0.0-alpha.9

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.
Files changed (3) hide show
  1. package/dist/index.js +28 -10
  2. package/dist/index.js.map +18 -18
  3. package/package.json +131 -129
package/dist/index.js CHANGED
@@ -2,7 +2,11 @@
2
2
  import { EventEmitter as EventEmitter4 } from "node:events";
3
3
 
4
4
  // src/actions/sendMessage.ts
5
- import { composePromptFromState, ModelType, parseJSONObjectFromText } from "@elizaos/core";
5
+ import {
6
+ composePromptFromState,
7
+ ModelType,
8
+ parseJSONObjectFromText
9
+ } from "@elizaos/core";
6
10
  var WHATSAPP_SEND_MESSAGE_ACTION = "WHATSAPP_SEND_MESSAGE";
7
11
  var SEND_MESSAGE_TEMPLATE = `
8
12
  You are extracting WhatsApp message parameters from a conversation.
@@ -23,14 +27,19 @@ Respond with a JSON object:
23
27
  `;
24
28
  var sendMessageAction = {
25
29
  name: WHATSAPP_SEND_MESSAGE_ACTION,
26
- similes: ["SEND_WHATSAPP", "WHATSAPP_MESSAGE", "TEXT_WHATSAPP", "SEND_WHATSAPP_MESSAGE"],
30
+ similes: [
31
+ "SEND_WHATSAPP",
32
+ "WHATSAPP_MESSAGE",
33
+ "TEXT_WHATSAPP",
34
+ "SEND_WHATSAPP_MESSAGE"
35
+ ],
27
36
  description: "Send a text message via WhatsApp",
28
37
  validate: async (runtime, message, state, options) => {
29
38
  const __avTextRaw = typeof message?.content?.text === "string" ? message.content.text : "";
30
39
  const __avText = __avTextRaw.toLowerCase();
31
40
  const __avKeywords = ["whatsapp", "send", "message"];
32
41
  const __avKeywordOk = __avKeywords.length > 0 && __avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));
33
- const __avRegex = new RegExp("\\b(?:whatsapp|send|message)\\b", "i");
42
+ const __avRegex = /\b(?:whatsapp|send|message)\b/i;
34
43
  const __avRegexOk = __avRegex.test(__avText);
35
44
  const __avSource = String(message?.content?.source ?? message?.source ?? "");
36
45
  const __avExpectedSource = "whatsapp";
@@ -180,7 +189,11 @@ var sendMessageAction = {
180
189
  ]
181
190
  };
182
191
  // src/actions/sendReaction.ts
183
- import { composePromptFromState as composePromptFromState2, ModelType as ModelType2, parseJSONObjectFromText as parseJSONObjectFromText2 } from "@elizaos/core";
192
+ import {
193
+ composePromptFromState as composePromptFromState2,
194
+ ModelType as ModelType2,
195
+ parseJSONObjectFromText as parseJSONObjectFromText2
196
+ } from "@elizaos/core";
184
197
  var WHATSAPP_SEND_REACTION_ACTION = "WHATSAPP_SEND_REACTION";
185
198
  var REACTION_TEMPLATE = `
186
199
  You are extracting WhatsApp reaction parameters from a conversation.
@@ -208,7 +221,7 @@ var sendReactionAction = {
208
221
  const __avText = __avTextRaw.toLowerCase();
209
222
  const __avKeywords = ["whatsapp", "send", "reaction"];
210
223
  const __avKeywordOk = __avKeywords.length > 0 && __avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));
211
- const __avRegex = new RegExp("\\b(?:whatsapp|send|reaction)\\b", "i");
224
+ const __avRegex = /\b(?:whatsapp|send|reaction)\b/i;
212
225
  const __avRegexOk = __avRegex.test(__avText);
213
226
  const __avSource = String(message?.content?.source ?? message?.source ?? "");
214
227
  const __avExpectedSource = "whatsapp";
@@ -348,8 +361,8 @@ var sendReactionAction = {
348
361
  ]
349
362
  };
350
363
  // src/client.ts
351
- import axios from "axios";
352
364
  import { EventEmitter } from "node:events";
365
+ import axios from "axios";
353
366
  var DEFAULT_API_VERSION = "v24.0";
354
367
 
355
368
  class WhatsAppClient extends EventEmitter {
@@ -698,8 +711,10 @@ class BaileysAuthManager {
698
711
  }
699
712
 
700
713
  // src/baileys/connection.ts
701
- import makeWASocket, { DisconnectReason } from "@whiskeysockets/baileys";
702
714
  import { EventEmitter as EventEmitter2 } from "node:events";
715
+ import makeWASocket, {
716
+ DisconnectReason
717
+ } from "@whiskeysockets/baileys";
703
718
  import pino from "pino";
704
719
 
705
720
  class BaileysConnection extends EventEmitter2 {
@@ -766,7 +781,7 @@ class BaileysConnection extends EventEmitter2 {
766
781
  try {
767
782
  this.reconnectAttempts += 1;
768
783
  const baseDelayMs = isQRTimeout ? 1000 : 3000;
769
- const backoffMs = Math.min(baseDelayMs * Math.pow(2, this.reconnectAttempts - 1), 30000);
784
+ const backoffMs = Math.min(baseDelayMs * 2 ** (this.reconnectAttempts - 1), 30000);
770
785
  await new Promise((resolve) => setTimeout(resolve, backoffMs));
771
786
  await this.connect();
772
787
  } catch (error) {
@@ -1039,7 +1054,10 @@ class WebhookHandler {
1039
1054
  }
1040
1055
  }
1041
1056
  // src/accounts.ts
1042
- import { checkPairingAllowed, isInAllowlist } from "@elizaos/core";
1057
+ import {
1058
+ checkPairingAllowed,
1059
+ isInAllowlist
1060
+ } from "@elizaos/core";
1043
1061
  var DEFAULT_ACCOUNT_ID = "default";
1044
1062
  function normalizeAccountId(accountId) {
1045
1063
  if (!accountId || typeof accountId !== "string") {
@@ -1591,5 +1609,5 @@ export {
1591
1609
  ClientFactory
1592
1610
  };
1593
1611
 
1594
- //# debugId=3ABF74EE0B1ACBEC64756E2164756E21
1612
+ //# debugId=2FB406236C995FEF64756E2164756E21
1595
1613
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -2,24 +2,24 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../src/actions/sendMessage.ts", "../src/actions/sendReaction.ts", "../src/client.ts", "../src/utils/config-detector.ts", "../src/clients/baileys-client.ts", "../src/baileys/auth.ts", "../src/baileys/connection.ts", "../src/baileys/message-adapter.ts", "../src/baileys/qr-code.ts", "../src/clients/factory.ts", "../src/handlers/message.handler.ts", "../src/handlers/webhook.handler.ts", "../src/accounts.ts", "../src/normalize.ts", "../src/types.ts"],
4
4
  "sourcesContent": [
5
- "import { EventEmitter } from \"node:events\";\nimport type { Plugin } from \"@elizaos/core\";\nimport { sendMessageAction, sendReactionAction } from \"./actions\";\nimport { ClientFactory } from \"./clients/factory\";\nimport type { IWhatsAppClient } from \"./clients/interface\";\nimport { MessageHandler, WebhookHandler } from \"./handlers\";\nimport type {\n ConnectionStatus,\n WhatsAppConfig,\n WhatsAppMessage,\n WhatsAppMessageResponse,\n WhatsAppWebhookEvent,\n} from \"./types\";\n\nexport class WhatsAppPlugin extends EventEmitter implements Plugin {\n private readonly client: IWhatsAppClient;\n private readonly messageHandler: MessageHandler;\n private readonly webhookHandler: WebhookHandler;\n\n name: string;\n description: string;\n actions = [sendMessageAction, sendReactionAction];\n\n constructor(config: WhatsAppConfig) {\n super();\n this.name = \"WhatsApp Plugin\";\n this.description = \"WhatsApp integration supporting Cloud API and Baileys (QR auth)\";\n this.client = ClientFactory.create(config);\n this.messageHandler = new MessageHandler(this.client);\n this.webhookHandler = new WebhookHandler();\n this.setupEventForwarding();\n }\n\n private setupEventForwarding(): void {\n this.client.on(\"message\", (payload) => this.emit(\"message\", payload));\n this.client.on(\"qr\", (payload) => this.emit(\"qr\", payload));\n this.client.on(\"ready\", () => this.emit(\"ready\"));\n this.client.on(\"connection\", (status) => this.emit(\"connection\", status));\n this.client.on(\"error\", (error) => this.emit(\"error\", error));\n }\n\n async start(): Promise<void> {\n await this.client.start();\n }\n\n async stop(): Promise<void> {\n await this.client.stop();\n }\n\n getConnectionStatus(): ConnectionStatus {\n return this.client.getConnectionStatus();\n }\n\n async sendMessage(message: WhatsAppMessage): Promise<WhatsAppMessageResponse> {\n return this.messageHandler.send(message);\n }\n\n async handleWebhook(event: WhatsAppWebhookEvent): Promise<void> {\n return this.webhookHandler.handle(event);\n }\n\n async verifyWebhook(token: string): Promise<boolean> {\n if (!this.client.verifyWebhook) {\n throw new Error(\"verifyWebhook is only supported by Cloud API authentication\");\n }\n return this.client.verifyWebhook(token);\n }\n}\n\nconst whatsappPlugin: Plugin = {\n name: \"whatsapp\",\n description: \"WhatsApp integration for ElizaOS (Cloud API + Baileys)\",\n actions: [sendMessageAction, sendReactionAction],\n};\n\nexport default whatsappPlugin;\n\n// Account management exports\nexport {\n checkWhatsAppUserAccess,\n DEFAULT_ACCOUNT_ID,\n isMultiAccountEnabled,\n isWhatsAppMentionRequired,\n isWhatsAppUserAllowed,\n listEnabledWhatsAppAccounts,\n listWhatsAppAccountIds,\n normalizeAccountId,\n type ResolvedWhatsAppAccount,\n resolveDefaultWhatsAppAccountId,\n resolveWhatsAppAccount,\n resolveWhatsAppGroupConfig,\n resolveWhatsAppToken,\n type WhatsAppAccessCheckResult,\n type WhatsAppAccountRuntimeConfig,\n type WhatsAppGroupRuntimeConfig,\n type WhatsAppMultiAccountConfig,\n type WhatsAppTokenResolution,\n type WhatsAppTokenSource,\n} from \"./accounts\";\n\n// Channel configuration types\nexport type {\n WhatsAppAccountConfig,\n WhatsAppAckReactionConfig,\n WhatsAppActionConfig,\n WhatsAppChannelConfig,\n WhatsAppGroupConfig,\n} from \"./config\";\n\n// Normalization and utility exports\nexport {\n buildWhatsAppUserJid,\n type ChunkWhatsAppTextOpts,\n chunkWhatsAppText,\n formatWhatsAppId,\n formatWhatsAppPhoneNumber,\n getWhatsAppChatType,\n isValidWhatsAppNumber,\n isWhatsAppGroup,\n isWhatsAppGroupJid,\n isWhatsAppUserTarget,\n normalizeE164,\n normalizeWhatsAppTarget,\n resolveWhatsAppSystemLocation,\n truncateText,\n WHATSAPP_TEXT_CHUNK_LIMIT,\n} from \"./normalize\";\n\nexport { ClientFactory } from \"./clients/factory\";\nexport * from \"./types\";\n",
6
- "import type {\n Action,\n ActionExample,\n ActionResult,\n HandlerCallback,\n HandlerOptions,\n IAgentRuntime,\n Memory,\n State,\n} from \"@elizaos/core\";\nimport { composePromptFromState, ModelType, parseJSONObjectFromText } from \"@elizaos/core\";\n\nexport const WHATSAPP_SEND_MESSAGE_ACTION = \"WHATSAPP_SEND_MESSAGE\";\n\nconst SEND_MESSAGE_TEMPLATE = `\nYou are extracting WhatsApp message parameters from a conversation.\n\nThe user wants to send a WhatsApp message. Extract the following:\n1. to: The phone number to send to (E.164 format, e.g., +14155552671)\n2. text: The message text to send\n\n{{recentMessages}}\n\nBased on the conversation, extract the message parameters.\n\nRespond with a JSON object:\n{\n \"to\": \"+14155552671\",\n \"text\": \"Hello from WhatsApp!\"\n}\n`;\n\ninterface SendMessageParams {\n to: string;\n text: string;\n}\n\nexport const sendMessageAction: Action = {\n name: WHATSAPP_SEND_MESSAGE_ACTION,\n similes: [\"SEND_WHATSAPP\", \"WHATSAPP_MESSAGE\", \"TEXT_WHATSAPP\", \"SEND_WHATSAPP_MESSAGE\"],\n description: \"Send a text message via WhatsApp\",\n\n validate: async (runtime: any, message: any, state?: any, options?: any): Promise<boolean> => {\n \tconst __avTextRaw = typeof message?.content?.text === 'string' ? message.content.text : '';\n \tconst __avText = __avTextRaw.toLowerCase();\n \tconst __avKeywords = ['whatsapp', 'send', 'message'];\n \tconst __avKeywordOk =\n \t\t__avKeywords.length > 0 &&\n \t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n \tconst __avRegex = new RegExp('\\\\b(?:whatsapp|send|message)\\\\b', 'i');\n \tconst __avRegexOk = __avRegex.test(__avText);\n \tconst __avSource = String(message?.content?.source ?? message?.source ?? '');\n \tconst __avExpectedSource = 'whatsapp';\n \tconst __avSourceOk = __avExpectedSource\n \t\t? __avSource === __avExpectedSource\n \t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n \tconst __avOptions = options && typeof options === 'object' ? options : {};\n \tconst __avInputOk =\n \t\t__avText.trim().length > 0 ||\n \t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n \t\tBoolean(message?.content && typeof message.content === 'object');\n\n \tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n \t\treturn false;\n \t}\n\n \tconst __avLegacyValidate = async (_runtime: IAgentRuntime, message: Memory): Promise<boolean> => {\n const source = message.content?.source;\n return source === \"whatsapp\";\n };\n \ttry {\n \t\treturn Boolean(await (__avLegacyValidate as any)(runtime, message, state, options));\n \t} catch {\n \t\treturn false;\n \t}\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state: State | undefined,\n _options?: HandlerOptions,\n callback?: HandlerCallback\n ): Promise<ActionResult> => {\n // Get WhatsApp settings\n const accessToken = runtime.getSetting(\"WHATSAPP_ACCESS_TOKEN\") as string;\n const phoneNumberId = runtime.getSetting(\"WHATSAPP_PHONE_NUMBER_ID\") as string;\n const apiVersion = (runtime.getSetting(\"WHATSAPP_API_VERSION\") as string) || \"v24.0\";\n\n if (!accessToken || !phoneNumberId) {\n if (callback) {\n await callback({\n text: \"WhatsApp is not configured. Missing access token or phone number ID.\",\n });\n }\n return { success: false, error: \"WhatsApp not configured\" };\n }\n\n const currentState = state ?? (await runtime.composeState(message));\n\n // Extract message parameters using LLM\n const prompt = composePromptFromState({\n state: currentState,\n template: SEND_MESSAGE_TEMPLATE,\n });\n\n let params: SendMessageParams;\n try {\n const response = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n const parsed = parseJSONObjectFromText(response) as unknown as SendMessageParams | null;\n if (!parsed || !parsed.to || !parsed.text) {\n // Try to use context from message\n const to = message.content?.from as string;\n const text = currentState.values?.response?.toString() || \"\";\n\n if (!to) {\n if (callback) {\n await callback({\n text: \"Could not determine who to send the message to\",\n });\n }\n return { success: false, error: \"Missing recipient\" };\n }\n\n // Validate text is not empty\n if (!text || text.trim() === \"\") {\n if (callback) {\n await callback({\n text: \"Cannot send an empty message. Please provide message content.\",\n });\n }\n return { success: false, error: \"Empty message text\" };\n }\n\n params = { to, text };\n } else {\n // Also validate that parsed text is not empty\n if (!parsed.text.trim()) {\n if (callback) {\n await callback({\n text: \"Cannot send an empty message. Please provide message content.\",\n });\n }\n return { success: false, error: \"Empty message text\" };\n }\n params = parsed;\n }\n } catch {\n if (callback) {\n await callback({\n text: \"Failed to parse message parameters\",\n });\n }\n return { success: false, error: \"Failed to parse message parameters\" };\n }\n\n // Send the message via WhatsApp Cloud API\n try {\n const url = `https://graph.facebook.com/${apiVersion}/${phoneNumberId}/messages`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n messaging_product: \"whatsapp\",\n recipient_type: \"individual\",\n to: params.to,\n type: \"text\",\n text: {\n preview_url: false,\n body: params.text,\n },\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json();\n throw new Error(errorData.error?.message || `HTTP ${response.status}`);\n }\n\n const data = (await response.json()) as { messages: Array<{ id: string }> };\n const messageId = data.messages?.[0]?.id;\n\n if (callback) {\n await callback({\n text: `Message sent to ${params.to}`,\n action: WHATSAPP_SEND_MESSAGE_ACTION,\n });\n }\n\n return {\n success: true,\n data: {\n action: WHATSAPP_SEND_MESSAGE_ACTION,\n to: params.to,\n messageId,\n },\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (callback) {\n await callback({\n text: `Failed to send WhatsApp message: ${errorMessage}`,\n });\n }\n return { success: false, error: errorMessage };\n }\n },\n\n examples: [\n [\n {\n name: \"{{name1}}\",\n content: {\n text: \"Send a WhatsApp message to +14155552671 saying hello\",\n },\n },\n {\n name: \"{{agentName}}\",\n content: {\n text: \"I'll send that WhatsApp message now.\",\n actions: [WHATSAPP_SEND_MESSAGE_ACTION],\n },\n },\n ],\n ] as ActionExample[][],\n};\n",
7
- "import type {\n Action,\n ActionExample,\n ActionResult,\n HandlerCallback,\n HandlerOptions,\n IAgentRuntime,\n Memory,\n State,\n} from \"@elizaos/core\";\nimport { composePromptFromState, ModelType, parseJSONObjectFromText } from \"@elizaos/core\";\n\nexport const WHATSAPP_SEND_REACTION_ACTION = \"WHATSAPP_SEND_REACTION\";\n\nconst REACTION_TEMPLATE = `\nYou are extracting WhatsApp reaction parameters from a conversation.\n\nThe user wants to react to a WhatsApp message. Extract the following:\n1. messageId: The ID of the message to react to\n2. emoji: The emoji to use as a reaction\n\n{{recentMessages}}\n\nBased on the conversation, extract the reaction parameters.\n\nRespond with a JSON object:\n{\n \"messageId\": \"wamid.xxx\",\n \"emoji\": \"👍\"\n}\n`;\n\ninterface ReactionParams {\n messageId: string;\n emoji: string;\n}\n\nexport const sendReactionAction: Action = {\n name: WHATSAPP_SEND_REACTION_ACTION,\n similes: [\"WHATSAPP_REACT\", \"REACT_WHATSAPP\", \"WHATSAPP_EMOJI\"],\n description: \"Send a reaction emoji to a WhatsApp message\",\n\n validate: async (runtime: any, message: any, state?: any, options?: any): Promise<boolean> => {\n \tconst __avTextRaw = typeof message?.content?.text === 'string' ? message.content.text : '';\n \tconst __avText = __avTextRaw.toLowerCase();\n \tconst __avKeywords = ['whatsapp', 'send', 'reaction'];\n \tconst __avKeywordOk =\n \t\t__avKeywords.length > 0 &&\n \t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n \tconst __avRegex = new RegExp('\\\\b(?:whatsapp|send|reaction)\\\\b', 'i');\n \tconst __avRegexOk = __avRegex.test(__avText);\n \tconst __avSource = String(message?.content?.source ?? message?.source ?? '');\n \tconst __avExpectedSource = 'whatsapp';\n \tconst __avSourceOk = __avExpectedSource\n \t\t? __avSource === __avExpectedSource\n \t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n \tconst __avOptions = options && typeof options === 'object' ? options : {};\n \tconst __avInputOk =\n \t\t__avText.trim().length > 0 ||\n \t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n \t\tBoolean(message?.content && typeof message.content === 'object');\n\n \tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n \t\treturn false;\n \t}\n\n \tconst __avLegacyValidate = async (_runtime: IAgentRuntime, message: Memory): Promise<boolean> => {\n const source = message.content?.source;\n return source === \"whatsapp\";\n };\n \ttry {\n \t\treturn Boolean(await (__avLegacyValidate as any)(runtime, message, state, options));\n \t} catch {\n \t\treturn false;\n \t}\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state: State | undefined,\n _options?: HandlerOptions,\n callback?: HandlerCallback\n ): Promise<ActionResult> => {\n // Get WhatsApp settings\n const accessToken = runtime.getSetting(\"WHATSAPP_ACCESS_TOKEN\") as string;\n const phoneNumberId = runtime.getSetting(\"WHATSAPP_PHONE_NUMBER_ID\") as string;\n const apiVersion = (runtime.getSetting(\"WHATSAPP_API_VERSION\") as string) || \"v24.0\";\n\n if (!accessToken || !phoneNumberId) {\n if (callback) {\n await callback({\n text: \"WhatsApp is not configured. Missing access token or phone number ID.\",\n });\n }\n return { success: false, error: \"WhatsApp not configured\" };\n }\n\n const currentState = state ?? (await runtime.composeState(message));\n\n // Extract reaction parameters using LLM\n const prompt = composePromptFromState({\n state: currentState,\n template: REACTION_TEMPLATE,\n });\n\n let params: ReactionParams;\n try {\n const response = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n const parsed = parseJSONObjectFromText(response) as unknown as ReactionParams | null;\n if (!parsed || !parsed.messageId || !parsed.emoji) {\n // Try to use context from message\n const messageId = message.content?.messageId as string;\n if (!messageId) {\n if (callback) {\n await callback({\n text: \"Could not determine which message to react to\",\n });\n }\n return { success: false, error: \"Missing message ID\" };\n }\n params = { messageId, emoji: \"👍\" }; // Default to thumbs up\n } else {\n params = parsed;\n }\n } catch {\n if (callback) {\n await callback({\n text: \"Failed to parse reaction parameters\",\n });\n }\n return { success: false, error: \"Failed to parse reaction parameters\" };\n }\n\n // Get the recipient (sender of the original message)\n const to = message.content?.from as string;\n if (!to) {\n if (callback) {\n await callback({\n text: \"Could not determine the recipient for the reaction\",\n });\n }\n return { success: false, error: \"Missing recipient\" };\n }\n\n // Send the reaction via WhatsApp Cloud API\n try {\n const url = `https://graph.facebook.com/${apiVersion}/${phoneNumberId}/messages`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n messaging_product: \"whatsapp\",\n recipient_type: \"individual\",\n to,\n type: \"reaction\",\n reaction: {\n message_id: params.messageId,\n emoji: params.emoji,\n },\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json();\n throw new Error(errorData.error?.message || `HTTP ${response.status}`);\n }\n\n if (callback) {\n await callback({\n text: `Reacted with ${params.emoji}`,\n action: WHATSAPP_SEND_REACTION_ACTION,\n });\n }\n\n return {\n success: true,\n data: {\n action: WHATSAPP_SEND_REACTION_ACTION,\n messageId: params.messageId,\n emoji: params.emoji,\n },\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (callback) {\n await callback({\n text: `Failed to send reaction: ${errorMessage}`,\n });\n }\n return { success: false, error: errorMessage };\n }\n },\n\n examples: [\n [\n {\n name: \"{{name1}}\",\n content: {\n text: \"React with a thumbs up\",\n },\n },\n {\n name: \"{{agentName}}\",\n content: {\n text: \"I'll add that reaction.\",\n actions: [WHATSAPP_SEND_REACTION_ACTION],\n },\n },\n ],\n ] as ActionExample[][],\n};\n",
8
- "import axios, { type AxiosInstance, type AxiosResponse } from \"axios\";\nimport { EventEmitter } from \"node:events\";\nimport type { IWhatsAppClient } from \"./clients/interface\";\nimport type {\n CloudAPIConfig,\n ConnectionStatus,\n SendReactionParams,\n SendReactionResult,\n WhatsAppInteractiveMessage,\n WhatsAppLocationMessage,\n WhatsAppMediaMessage,\n WhatsAppMessage,\n WhatsAppMessageResponse,\n WhatsAppReactionMessage,\n} from \"./types\";\n\nconst DEFAULT_API_VERSION = \"v24.0\";\n\nexport class WhatsAppClient extends EventEmitter implements IWhatsAppClient {\n private client: AxiosInstance;\n private config: CloudAPIConfig;\n private connectionStatus: ConnectionStatus = \"close\";\n\n constructor(config: CloudAPIConfig) {\n super();\n this.config = config;\n const apiVersion = config.apiVersion || DEFAULT_API_VERSION;\n\n this.client = axios.create({\n baseURL: `https://graph.facebook.com/${apiVersion}`,\n headers: {\n Authorization: `Bearer ${config.accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n });\n }\n\n async start(): Promise<void> {\n this.connectionStatus = \"open\";\n this.emit(\"connection\", \"open\");\n this.emit(\"ready\");\n }\n\n async stop(): Promise<void> {\n this.connectionStatus = \"close\";\n this.emit(\"connection\", \"close\");\n }\n\n getConnectionStatus(): ConnectionStatus {\n return this.connectionStatus;\n }\n\n /**\n * Get the configured phone number ID.\n */\n getPhoneNumberId(): string {\n return this.config.phoneNumberId;\n }\n\n /**\n * Send a message of any supported type.\n */\n async sendMessage(message: WhatsAppMessage): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n const endpoint = `/${this.config.phoneNumberId}/messages`;\n const payload = this.buildMessagePayload(message);\n return this.client.post(endpoint, payload);\n }\n\n /**\n * Send a text message.\n */\n async sendTextMessage(\n to: string,\n text: string,\n _previewUrl = false\n ): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n return this.sendMessage({\n type: \"text\",\n to,\n content: text,\n });\n }\n\n /**\n * Send a reaction to a message.\n */\n async sendReaction(params: SendReactionParams): Promise<SendReactionResult> {\n const endpoint = `/${this.config.phoneNumberId}/messages`;\n\n const payload = {\n messaging_product: \"whatsapp\",\n recipient_type: \"individual\",\n to: params.to,\n type: \"reaction\",\n reaction: {\n message_id: params.messageId,\n emoji: params.emoji,\n },\n };\n\n try {\n const response = await this.client.post<WhatsAppMessageResponse>(endpoint, payload);\n return {\n success: true,\n messageId: response.data.messages?.[0]?.id,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n error: errorMessage,\n };\n }\n }\n\n /**\n * Remove a reaction from a message (send empty emoji).\n */\n async removeReaction(to: string, messageId: string): Promise<SendReactionResult> {\n return this.sendReaction({\n to,\n messageId,\n emoji: \"\",\n });\n }\n\n /**\n * Send an image message.\n */\n async sendImage(\n to: string,\n imageUrl: string,\n caption?: string\n ): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n return this.sendMessage({\n type: \"image\",\n to,\n content: {\n link: imageUrl,\n caption,\n } as WhatsAppMediaMessage,\n });\n }\n\n /**\n * Send a video message.\n */\n async sendVideo(\n to: string,\n videoUrl: string,\n caption?: string\n ): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n return this.sendMessage({\n type: \"video\",\n to,\n content: {\n link: videoUrl,\n caption,\n } as WhatsAppMediaMessage,\n });\n }\n\n /**\n * Send an audio message.\n */\n async sendAudio(to: string, audioUrl: string): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n return this.sendMessage({\n type: \"audio\",\n to,\n content: {\n link: audioUrl,\n } as WhatsAppMediaMessage,\n });\n }\n\n /**\n * Send a document message.\n */\n async sendDocument(\n to: string,\n documentUrl: string,\n filename?: string,\n caption?: string\n ): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n return this.sendMessage({\n type: \"document\",\n to,\n content: {\n link: documentUrl,\n filename,\n caption,\n } as WhatsAppMediaMessage,\n });\n }\n\n /**\n * Send a location message.\n */\n async sendLocation(\n to: string,\n latitude: number,\n longitude: number,\n name?: string,\n address?: string\n ): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n return this.sendMessage({\n type: \"location\",\n to,\n content: {\n latitude,\n longitude,\n name,\n address,\n } as WhatsAppLocationMessage,\n });\n }\n\n /**\n * Send an interactive button message.\n */\n async sendButtonMessage(\n to: string,\n bodyText: string,\n buttons: Array<{ id: string; title: string }>,\n headerText?: string,\n footerText?: string\n ): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n const interactive: WhatsAppInteractiveMessage = {\n type: \"button\",\n body: { text: bodyText },\n action: {\n buttons: buttons.map((btn) => ({\n type: \"reply\" as const,\n reply: { id: btn.id, title: btn.title },\n })),\n },\n };\n\n if (headerText) {\n interactive.header = { type: \"text\", text: headerText };\n }\n if (footerText) {\n interactive.footer = { text: footerText };\n }\n\n return this.sendMessage({\n type: \"interactive\",\n to,\n content: interactive,\n });\n }\n\n /**\n * Send an interactive list message.\n */\n async sendListMessage(\n to: string,\n bodyText: string,\n buttonText: string,\n sections: Array<{\n title?: string;\n rows: Array<{ id: string; title: string; description?: string }>;\n }>,\n headerText?: string,\n footerText?: string\n ): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n const interactive: WhatsAppInteractiveMessage = {\n type: \"list\",\n body: { text: bodyText },\n action: {\n button: buttonText,\n sections,\n },\n };\n\n if (headerText) {\n interactive.header = { type: \"text\", text: headerText };\n }\n if (footerText) {\n interactive.footer = { text: footerText };\n }\n\n return this.sendMessage({\n type: \"interactive\",\n to,\n content: interactive,\n });\n }\n\n /**\n * Mark a message as read.\n */\n async markMessageAsRead(messageId: string): Promise<boolean> {\n const endpoint = `/${this.config.phoneNumberId}/messages`;\n\n const payload = {\n messaging_product: \"whatsapp\",\n status: \"read\",\n message_id: messageId,\n };\n\n try {\n await this.client.post(endpoint, payload);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Download media by ID.\n */\n async getMediaUrl(mediaId: string): Promise<string | null> {\n try {\n const response = await this.client.get(`/${mediaId}`);\n return response.data.url || null;\n } catch {\n return null;\n }\n }\n\n /**\n * Verify webhook token.\n */\n async verifyWebhook(token: string): Promise<boolean> {\n return token === this.config.webhookVerifyToken;\n }\n\n /**\n * Build the message payload based on message type.\n */\n private buildMessagePayload(message: WhatsAppMessage): Record<string, unknown> {\n const basePayload = {\n messaging_product: \"whatsapp\",\n recipient_type: \"individual\",\n to: message.to,\n type: message.type,\n };\n\n // Add context for replies\n const contextPayload = message.replyToMessageId\n ? { context: { message_id: message.replyToMessageId } }\n : {};\n\n switch (message.type) {\n case \"text\":\n return {\n ...basePayload,\n ...contextPayload,\n text: {\n body: message.content as string,\n },\n };\n\n case \"template\":\n return {\n ...basePayload,\n ...contextPayload,\n template: message.content,\n };\n\n case \"image\": {\n const imageContent = message.content as WhatsAppMediaMessage;\n return {\n ...basePayload,\n ...contextPayload,\n image: {\n link: imageContent.link,\n caption: imageContent.caption,\n },\n };\n }\n\n case \"video\": {\n const videoContent = message.content as WhatsAppMediaMessage;\n return {\n ...basePayload,\n ...contextPayload,\n video: {\n link: videoContent.link,\n caption: videoContent.caption,\n },\n };\n }\n\n case \"audio\": {\n const audioContent = message.content as WhatsAppMediaMessage;\n return {\n ...basePayload,\n ...contextPayload,\n audio: {\n link: audioContent.link,\n },\n };\n }\n\n case \"document\": {\n const docContent = message.content as WhatsAppMediaMessage;\n return {\n ...basePayload,\n ...contextPayload,\n document: {\n link: docContent.link,\n filename: docContent.filename,\n caption: docContent.caption,\n },\n };\n }\n\n case \"location\": {\n const locContent = message.content as WhatsAppLocationMessage;\n return {\n ...basePayload,\n ...contextPayload,\n location: {\n latitude: locContent.latitude,\n longitude: locContent.longitude,\n name: locContent.name,\n address: locContent.address,\n },\n };\n }\n\n case \"reaction\": {\n const reactionContent = message.content as WhatsAppReactionMessage;\n return {\n ...basePayload,\n reaction: {\n message_id: reactionContent.messageId,\n emoji: reactionContent.emoji,\n },\n };\n }\n\n case \"interactive\": {\n const interactiveContent = message.content as WhatsAppInteractiveMessage;\n return {\n ...basePayload,\n ...contextPayload,\n interactive: interactiveContent,\n };\n }\n\n default:\n return basePayload;\n }\n }\n}\n",
9
- "import type { WhatsAppConfig } from \"../types\";\n\nexport function detectAuthMethod(config: WhatsAppConfig | Record<string, unknown>): \"baileys\" | \"cloudapi\" {\n const explicitMethod = (config as { authMethod?: unknown }).authMethod;\n if (explicitMethod !== undefined) {\n if (explicitMethod === \"baileys\" || explicitMethod === \"cloudapi\") {\n return explicitMethod;\n }\n throw new Error(\n `Invalid authMethod: \"${String(explicitMethod)}\". Must be either \"baileys\" or \"cloudapi\".`\n );\n }\n\n if (\"authDir\" in config && config.authDir) {\n return \"baileys\";\n }\n\n if (\"accessToken\" in config && \"phoneNumberId\" in config) {\n return \"cloudapi\";\n }\n\n throw new Error(\n \"Cannot detect auth method. Provide either authDir (Baileys) or accessToken + phoneNumberId (Cloud API).\"\n );\n}\n",
10
- "import { EventEmitter } from \"node:events\";\nimport { BaileysAuthManager } from \"../baileys/auth\";\nimport { BaileysConnection } from \"../baileys/connection\";\nimport { MessageAdapter } from \"../baileys/message-adapter\";\nimport { QRCodeGenerator } from \"../baileys/qr-code\";\nimport type { IWhatsAppClient } from \"./interface\";\nimport type { BaileysConfig, ConnectionStatus, WhatsAppMessage, WhatsAppMessageResponse } from \"../types\";\n\nexport class BaileysClient extends EventEmitter implements IWhatsAppClient {\n private readonly config: BaileysConfig;\n private readonly authManager: BaileysAuthManager;\n private readonly connection: BaileysConnection;\n private readonly qrGenerator: QRCodeGenerator;\n private readonly adapter: MessageAdapter;\n\n constructor(config: BaileysConfig) {\n super();\n this.config = config;\n this.authManager = new BaileysAuthManager(config.authDir);\n this.connection = new BaileysConnection(this.authManager);\n this.qrGenerator = new QRCodeGenerator();\n this.adapter = new MessageAdapter();\n this.setupEventForwarding();\n }\n\n private setupEventForwarding(): void {\n this.connection.on(\"qr\", async (qr: string) => {\n try {\n const qrData = await this.qrGenerator.generate(qr);\n if (this.config.printQRInTerminal !== false) {\n console.log(\"\\n=== Scan QR Code ===\\n\");\n console.log(qrData.terminal);\n }\n this.emit(\"qr\", qrData);\n } catch (error) {\n this.emit(\"error\", error);\n }\n });\n\n this.connection.on(\"connection\", (status: ConnectionStatus) => {\n this.emit(\"connection\", status);\n if (status === \"open\") {\n this.emit(\"ready\");\n }\n });\n\n this.connection.on(\"messages\", (messages: unknown[]) => {\n for (const message of messages) {\n const maybe = message as { key?: { fromMe?: boolean }; message?: unknown };\n if (!maybe.key?.fromMe && maybe.message) {\n this.emit(\"message\", this.adapter.toUnified(message as any));\n }\n }\n });\n\n this.connection.on(\"error\", (error: unknown) => {\n this.emit(\"error\", error);\n });\n }\n\n async start(): Promise<void> {\n await this.connection.connect();\n }\n\n async stop(): Promise<void> {\n await this.connection.disconnect();\n }\n\n async sendMessage(message: WhatsAppMessage): Promise<WhatsAppMessageResponse> {\n const socket = this.connection.getSocket();\n if (!socket) {\n throw new Error(\"Not connected to WhatsApp via Baileys\");\n }\n\n const payload = this.adapter.toBaileys(message);\n const result = await socket.sendMessage(message.to, payload as any);\n const id = result?.key?.id ?? \"\";\n\n return {\n messaging_product: \"whatsapp\",\n contacts: [{ input: message.to, wa_id: message.to }],\n messages: [{ id }],\n };\n }\n\n getConnectionStatus(): ConnectionStatus {\n return this.connection.getStatus();\n }\n}\n",
11
- "import { useMultiFileAuthState } from \"@whiskeysockets/baileys\";\nimport type { AuthenticationState } from \"@whiskeysockets/baileys\";\n\nexport class BaileysAuthManager {\n private readonly authDir: string;\n private state?: AuthenticationState;\n private saveCreds?: () => Promise<void>;\n\n constructor(authDir: string) {\n this.authDir = authDir;\n }\n\n async initialize(): Promise<AuthenticationState> {\n const result = await useMultiFileAuthState(this.authDir);\n this.state = result.state;\n this.saveCreds = result.saveCreds;\n return this.state;\n }\n\n async save(): Promise<void> {\n if (this.saveCreds) {\n await this.saveCreds();\n }\n }\n}\n",
12
- "import makeWASocket, { DisconnectReason, type WASocket } from \"@whiskeysockets/baileys\";\nimport { Boom } from \"@hapi/boom\";\nimport { EventEmitter } from \"node:events\";\nimport pino from \"pino\";\nimport type { BaileysAuthManager } from \"./auth\";\nimport type { ConnectionStatus } from \"../types\";\n\nexport class BaileysConnection extends EventEmitter {\n private socket?: WASocket;\n private readonly authManager: BaileysAuthManager;\n private connectionStatus: ConnectionStatus = \"close\";\n private reconnecting = false;\n private reconnectAttempts = 0;\n private readonly maxReconnectAttempts = 10;\n\n constructor(authManager: BaileysAuthManager) {\n super();\n this.authManager = authManager;\n }\n\n async connect(): Promise<WASocket> {\n this.connectionStatus = \"connecting\";\n this.emit(\"connection\", \"connecting\");\n\n const state = await this.authManager.initialize();\n this.socket = makeWASocket({\n auth: state,\n printQRInTerminal: false,\n logger: pino({ level: \"silent\" }),\n browser: [\"Chrome (Linux)\", \"\", \"\"],\n });\n\n this.setupEventHandlers();\n return this.socket;\n }\n\n private setupEventHandlers(): void {\n if (!this.socket) {\n return;\n }\n\n this.socket.ev.on(\"connection.update\", async (update) => {\n const { connection, qr, lastDisconnect } = update;\n\n if (qr) {\n this.emit(\"qr\", qr);\n }\n\n if (connection) {\n this.connectionStatus = connection;\n this.emit(\"connection\", connection);\n }\n\n if (connection === \"open\") {\n this.reconnectAttempts = 0;\n return;\n }\n\n if (connection !== \"close\") {\n return;\n }\n\n const statusCode = (lastDisconnect?.error as Boom | undefined)?.output?.statusCode;\n const isQRTimeout = statusCode === 515;\n const shouldReconnect = statusCode !== DisconnectReason.loggedOut && statusCode !== 405;\n\n if (lastDisconnect?.error && !isQRTimeout) {\n this.emit(\"error\", lastDisconnect.error);\n }\n\n if (!shouldReconnect) {\n return;\n }\n\n if (this.reconnecting) {\n return;\n }\n\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n this.emit(\"error\", new Error(\"Max reconnection attempts reached\"));\n return;\n }\n\n this.reconnecting = true;\n try {\n this.reconnectAttempts += 1;\n const baseDelayMs = isQRTimeout ? 1000 : 3000;\n const backoffMs = Math.min(\n baseDelayMs * Math.pow(2, this.reconnectAttempts - 1),\n 30000\n );\n await new Promise((resolve) => setTimeout(resolve, backoffMs));\n await this.connect();\n } catch (error) {\n this.emit(\"error\", error);\n } finally {\n this.reconnecting = false;\n }\n });\n\n this.socket.ev.on(\"creds.update\", async () => {\n await this.authManager.save();\n });\n\n this.socket.ev.on(\"messages.upsert\", ({ messages }) => {\n this.emit(\"messages\", messages);\n });\n }\n\n getSocket(): WASocket | undefined {\n return this.socket;\n }\n\n getStatus(): ConnectionStatus {\n return this.connectionStatus;\n }\n\n async disconnect(): Promise<void> {\n if (!this.socket) {\n return;\n }\n\n (\n this.socket.ev as unknown as {\n removeAllListeners: (...args: unknown[]) => void;\n }\n ).removeAllListeners();\n (this.socket as unknown as { ws?: { close?: () => void } }).ws?.close?.();\n this.socket = undefined;\n this.connectionStatus = \"close\";\n this.emit(\"connection\", \"close\");\n }\n}\n",
13
- "import type { proto } from \"@whiskeysockets/baileys\";\nimport type {\n UnifiedMessage,\n WhatsAppMediaMessage,\n WhatsAppMessage,\n WhatsAppTemplate,\n} from \"../types\";\n\nexport class MessageAdapter {\n toUnified(msg: proto.IWebMessageInfo): UnifiedMessage {\n return {\n id: msg.key?.id ?? \"\",\n from: msg.key?.remoteJid ?? \"\",\n timestamp: Number(msg.messageTimestamp ?? 0),\n type: this.detectType(msg),\n content: this.extractContent(msg),\n };\n }\n\n toBaileys(msg: WhatsAppMessage): Record<string, unknown> {\n switch (msg.type) {\n case \"text\":\n return { text: msg.content as string };\n case \"image\":\n return this.mediaWithCaption(\"image\", msg.content as WhatsAppMediaMessage);\n case \"video\":\n return this.mediaWithCaption(\"video\", msg.content as WhatsAppMediaMessage);\n case \"audio\":\n return this.mediaNoCaption(\"audio\", msg.content as WhatsAppMediaMessage);\n case \"document\":\n return this.mediaWithFilename(msg.content as WhatsAppMediaMessage);\n case \"template\":\n return { text: this.renderTemplate(msg.content as WhatsAppTemplate) };\n default:\n throw new Error(`Message type ${msg.type} is not yet supported for Baileys`);\n }\n }\n\n private mediaWithCaption(\n key: \"image\" | \"video\",\n media: WhatsAppMediaMessage\n ): Record<string, unknown> {\n if (!media?.link) {\n throw new Error(`${key} message requires a media link`);\n }\n return {\n [key]: { url: media.link },\n ...(media.caption ? { caption: media.caption } : {}),\n };\n }\n\n private mediaNoCaption(\n key: \"audio\",\n media: WhatsAppMediaMessage\n ): Record<string, unknown> {\n if (!media?.link) {\n throw new Error(`${key} message requires a media link`);\n }\n return { [key]: { url: media.link } };\n }\n\n private mediaWithFilename(media: WhatsAppMediaMessage): Record<string, unknown> {\n if (!media?.link) {\n throw new Error(\"document message requires a media link\");\n }\n return {\n document: { url: media.link },\n ...(media.filename ? { fileName: media.filename } : {}),\n ...(media.caption ? { caption: media.caption } : {}),\n };\n }\n\n private detectType(\n msg: proto.IWebMessageInfo\n ): \"text\" | \"image\" | \"audio\" | \"video\" | \"document\" {\n if (msg.message?.conversation || msg.message?.extendedTextMessage) {\n return \"text\";\n }\n if (msg.message?.imageMessage) {\n return \"image\";\n }\n if (msg.message?.audioMessage) {\n return \"audio\";\n }\n if (msg.message?.videoMessage) {\n return \"video\";\n }\n if (msg.message?.documentMessage) {\n return \"document\";\n }\n return \"text\";\n }\n\n private extractContent(msg: proto.IWebMessageInfo): string {\n return msg.message?.conversation ?? msg.message?.extendedTextMessage?.text ?? \"\";\n }\n\n private renderTemplate(template: WhatsAppTemplate): string {\n const params = template.components?.flatMap((component) =>\n component.parameters.map((parameter) => parameter.text).filter(Boolean)\n );\n return params && params.length > 0\n ? `${template.name}: ${params.join(\", \")}`\n : template.name;\n }\n}\n",
14
- "import QRCode from \"qrcode\";\nimport QRCodeTerminal from \"qrcode-terminal\";\nimport type { QRCodeData } from \"../types\";\n\nexport class QRCodeGenerator {\n async generate(qrString: string): Promise<QRCodeData> {\n return {\n terminal: await this.generateTerminal(qrString),\n dataURL: await QRCode.toDataURL(qrString),\n raw: qrString,\n };\n }\n\n private async generateTerminal(qr: string): Promise<string> {\n return new Promise((resolve) => {\n QRCodeTerminal.generate(qr, { small: true }, (output: string) => {\n resolve(output);\n });\n });\n }\n}\n",
15
- "import { WhatsAppClient } from \"../client\";\nimport type { BaileysConfig, CloudAPIConfig, WhatsAppConfig } from \"../types\";\nimport { detectAuthMethod } from \"../utils/config-detector\";\nimport { BaileysClient } from \"./baileys-client\";\nimport type { IWhatsAppClient } from \"./interface\";\n\nexport class ClientFactory {\n static create(config: WhatsAppConfig): IWhatsAppClient {\n const authMethod = detectAuthMethod(config);\n if (authMethod === \"baileys\") {\n return new BaileysClient(config as BaileysConfig);\n }\n return new WhatsAppClient(config as CloudAPIConfig);\n }\n}\n",
16
- "import type { IWhatsAppClient } from \"../clients/interface\";\nimport type { WhatsAppMessage, WhatsAppMessageResponse } from \"../types\";\n\nexport class MessageHandler {\n constructor(private client: IWhatsAppClient) {}\n\n async send(message: WhatsAppMessage): Promise<WhatsAppMessageResponse> {\n try {\n const response = await this.client.sendMessage(message);\n if (response && typeof response === \"object\" && \"data\" in response) {\n return (response as { data: WhatsAppMessageResponse }).data;\n }\n return response as WhatsAppMessageResponse;\n } catch (error: unknown) {\n if (error instanceof Error) {\n throw new Error(`Failed to send WhatsApp message: ${error.message}`);\n }\n throw new Error(\"Failed to send WhatsApp message\");\n }\n }\n}\n",
17
- "import type { WhatsAppIncomingMessage, WhatsAppStatusUpdate, WhatsAppWebhookEvent } from \"../types\";\n\nexport class WebhookHandler {\n async handle(event: WhatsAppWebhookEvent): Promise<void> {\n try {\n // Process messages\n if (event.entry?.[0]?.changes?.[0]?.value?.messages) {\n const messages = event.entry[0].changes[0].value.messages;\n for (const message of messages) {\n await this.handleMessage(message);\n }\n }\n\n // Process status updates\n if (event.entry?.[0]?.changes?.[0]?.value?.statuses) {\n const statuses = event.entry[0].changes[0].value.statuses;\n for (const status of statuses) {\n await this.handleStatus(status);\n }\n }\n } catch (error: unknown) {\n if (error instanceof Error) {\n throw new Error(`Failed to send WhatsApp message: ${error.message}`);\n }\n throw new Error(\"Failed to send WhatsApp message\");\n }\n }\n\n private async handleMessage(message: WhatsAppIncomingMessage): Promise<void> {\n // Implement message handling logic\n // This could emit events or trigger callbacks based on your framework's needs\n console.log(\"Received message:\", message);\n }\n\n private async handleStatus(status: WhatsAppStatusUpdate): Promise<void> {\n // Implement status update handling logic\n // This could emit events or trigger callbacks based on your framework's needs\n console.log(\"Received status update:\", status);\n }\n}\n",
18
- "import type { IAgentRuntime } from \"@elizaos/core\";\nimport { checkPairingAllowed, isInAllowlist, type PairingCheckResult } from \"@elizaos/core\";\n\n/**\n * Default account identifier used when no specific account is configured\n */\nexport const DEFAULT_ACCOUNT_ID = \"default\";\n\n/**\n * Token source indicator\n */\nexport type WhatsAppTokenSource = \"config\" | \"env\" | \"character\" | \"none\";\n\n/**\n * Group-specific runtime configuration (for account resolution)\n */\nexport interface WhatsAppGroupRuntimeConfig {\n /** If false, ignore messages from this group */\n enabled?: boolean;\n /** Allowlist for users in this group */\n allowFrom?: Array<string | number>;\n /** Require bot mention to respond */\n requireMention?: boolean;\n /** Custom system prompt for this group */\n systemPrompt?: string;\n /** Skills enabled for this group */\n skills?: string[];\n}\n\n/**\n * Configuration for a single WhatsApp account (runtime resolution)\n */\nexport interface WhatsAppAccountRuntimeConfig {\n /** Optional display name for this account */\n name?: string;\n /** If false, do not start this WhatsApp account */\n enabled?: boolean;\n /** WhatsApp Cloud API access token */\n accessToken?: string;\n /** Phone number ID from WhatsApp Business */\n phoneNumberId?: string;\n /** Business account ID */\n businessAccountId?: string;\n /** Webhook verification token */\n webhookVerifyToken?: string;\n /** API version to use */\n apiVersion?: string;\n /** Allowlist for DM senders */\n allowFrom?: Array<string | number>;\n /** Allowlist for groups */\n groupAllowFrom?: Array<string | number>;\n /** DM access policy */\n dmPolicy?: \"open\" | \"allowlist\" | \"pairing\" | \"disabled\";\n /** Group message access policy */\n groupPolicy?: \"open\" | \"allowlist\" | \"disabled\";\n /** Max media size in MB */\n mediaMaxMb?: number;\n /** Text chunk limit for messages */\n textChunkLimit?: number;\n /** Group-specific configurations */\n groups?: Record<string, WhatsAppGroupRuntimeConfig>;\n}\n\n/**\n * Multi-account WhatsApp configuration structure\n */\nexport interface WhatsAppMultiAccountConfig {\n /** Default/base configuration applied to all accounts */\n enabled?: boolean;\n accessToken?: string;\n phoneNumberId?: string;\n businessAccountId?: string;\n webhookVerifyToken?: string;\n apiVersion?: string;\n dmPolicy?: \"open\" | \"allowlist\" | \"pairing\" | \"disabled\";\n groupPolicy?: \"open\" | \"allowlist\" | \"disabled\";\n mediaMaxMb?: number;\n textChunkLimit?: number;\n /** Per-account configuration overrides */\n accounts?: Record<string, WhatsAppAccountRuntimeConfig>;\n /** Group configurations at base level */\n groups?: Record<string, WhatsAppGroupRuntimeConfig>;\n}\n\n/**\n * Token resolution result\n */\nexport interface WhatsAppTokenResolution {\n token: string;\n source: WhatsAppTokenSource;\n}\n\n/**\n * Resolved WhatsApp account with all configuration merged\n */\nexport interface ResolvedWhatsAppAccount {\n accountId: string;\n enabled: boolean;\n name?: string;\n accessToken: string;\n phoneNumberId: string;\n businessAccountId?: string;\n tokenSource: WhatsAppTokenSource;\n configured: boolean;\n config: WhatsAppAccountRuntimeConfig;\n}\n\n/**\n * Normalizes an account ID, returning the default if not provided\n */\nexport function normalizeAccountId(accountId?: string | null): string {\n if (!accountId || typeof accountId !== \"string\") {\n return DEFAULT_ACCOUNT_ID;\n }\n const trimmed = accountId.trim().toLowerCase();\n if (!trimmed || trimmed === \"default\") {\n return DEFAULT_ACCOUNT_ID;\n }\n return trimmed;\n}\n\n/**\n * Gets the multi-account configuration from runtime settings\n */\nexport function getMultiAccountConfig(runtime: IAgentRuntime): WhatsAppMultiAccountConfig {\n const characterWhatsApp = runtime.character?.settings?.whatsapp as\n | WhatsAppMultiAccountConfig\n | undefined;\n\n return {\n enabled: characterWhatsApp?.enabled,\n accessToken: characterWhatsApp?.accessToken,\n phoneNumberId: characterWhatsApp?.phoneNumberId,\n businessAccountId: characterWhatsApp?.businessAccountId,\n webhookVerifyToken: characterWhatsApp?.webhookVerifyToken,\n apiVersion: characterWhatsApp?.apiVersion,\n dmPolicy: characterWhatsApp?.dmPolicy,\n groupPolicy: characterWhatsApp?.groupPolicy,\n mediaMaxMb: characterWhatsApp?.mediaMaxMb,\n textChunkLimit: characterWhatsApp?.textChunkLimit,\n accounts: characterWhatsApp?.accounts,\n groups: characterWhatsApp?.groups,\n };\n}\n\n/**\n * Lists all configured account IDs\n */\nexport function listWhatsAppAccountIds(runtime: IAgentRuntime): string[] {\n const config = getMultiAccountConfig(runtime);\n const accounts = config.accounts;\n const ids = new Set<string>();\n\n // Check if default account is configured\n const envToken = runtime.getSetting(\"WHATSAPP_ACCESS_TOKEN\") as string | undefined;\n const envPhoneId = runtime.getSetting(\"WHATSAPP_PHONE_NUMBER_ID\") as string | undefined;\n\n const baseConfigured = Boolean(config.accessToken?.trim() && config.phoneNumberId?.trim());\n const envConfigured = Boolean(envToken?.trim() && envPhoneId?.trim());\n\n if (baseConfigured || envConfigured) {\n ids.add(DEFAULT_ACCOUNT_ID);\n }\n\n // Add named accounts\n if (accounts && typeof accounts === \"object\") {\n for (const id of Object.keys(accounts)) {\n if (id) {\n ids.add(normalizeAccountId(id));\n }\n }\n }\n\n const result = Array.from(ids);\n if (result.length === 0) {\n return [DEFAULT_ACCOUNT_ID];\n }\n\n return result.slice().sort((a, b) => a.localeCompare(b));\n}\n\n/**\n * Resolves the default account ID to use\n */\nexport function resolveDefaultWhatsAppAccountId(runtime: IAgentRuntime): string {\n const ids = listWhatsAppAccountIds(runtime);\n if (ids.includes(DEFAULT_ACCOUNT_ID)) {\n return DEFAULT_ACCOUNT_ID;\n }\n return ids[0] ?? DEFAULT_ACCOUNT_ID;\n}\n\n/**\n * Gets the account-specific configuration\n */\nfunction getAccountConfig(\n runtime: IAgentRuntime,\n accountId: string\n): WhatsAppAccountRuntimeConfig | undefined {\n const config = getMultiAccountConfig(runtime);\n const accounts = config.accounts;\n\n if (!accounts || typeof accounts !== \"object\") {\n return undefined;\n }\n\n // Try direct match first\n const direct = accounts[accountId];\n if (direct) {\n return direct;\n }\n\n // Try normalized match\n const normalized = normalizeAccountId(accountId);\n const matchKey = Object.keys(accounts).find((key) => normalizeAccountId(key) === normalized);\n return matchKey ? accounts[matchKey] : undefined;\n}\n\n/**\n * Resolves the access token for a WhatsApp account\n */\nexport function resolveWhatsAppToken(\n runtime: IAgentRuntime,\n accountId: string\n): WhatsAppTokenResolution {\n const multiConfig = getMultiAccountConfig(runtime);\n const accountConfig = getAccountConfig(runtime, accountId);\n\n // Check account-level config first\n if (accountConfig?.accessToken?.trim()) {\n return { token: accountConfig.accessToken.trim(), source: \"config\" };\n }\n\n // For default account, check base config\n if (accountId === DEFAULT_ACCOUNT_ID) {\n if (multiConfig.accessToken?.trim()) {\n return { token: multiConfig.accessToken.trim(), source: \"config\" };\n }\n\n // Check environment/runtime settings\n const envToken = runtime.getSetting(\"WHATSAPP_ACCESS_TOKEN\") as string | undefined;\n if (envToken?.trim()) {\n return { token: envToken.trim(), source: \"env\" };\n }\n }\n\n return { token: \"\", source: \"none\" };\n}\n\n/**\n * Merges base configuration with account-specific overrides\n */\n/**\n * Removes undefined values from an object to prevent them from overwriting during spread\n */\nfunction filterDefined<T extends object>(obj: T): Partial<T> {\n return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined)) as Partial<T>;\n}\n\nfunction mergeWhatsAppAccountConfig(\n runtime: IAgentRuntime,\n accountId: string\n): WhatsAppAccountRuntimeConfig {\n const multiConfig = getMultiAccountConfig(runtime);\n const { accounts: _ignored, ...baseConfig } = multiConfig;\n const accountConfig = getAccountConfig(runtime, accountId) ?? {};\n\n // Get environment/runtime settings for the base config\n const envToken = runtime.getSetting(\"WHATSAPP_ACCESS_TOKEN\") as string | undefined;\n const envPhoneId = runtime.getSetting(\"WHATSAPP_PHONE_NUMBER_ID\") as string | undefined;\n const envBusinessId = runtime.getSetting(\"WHATSAPP_BUSINESS_ACCOUNT_ID\") as string | undefined;\n const envWebhookToken = runtime.getSetting(\"WHATSAPP_WEBHOOK_VERIFY_TOKEN\") as string | undefined;\n const envDmPolicy = runtime.getSetting(\"WHATSAPP_DM_POLICY\") as string | undefined;\n const envGroupPolicy = runtime.getSetting(\"WHATSAPP_GROUP_POLICY\") as string | undefined;\n\n const envConfig: WhatsAppAccountRuntimeConfig = {\n accessToken: envToken || undefined,\n phoneNumberId: envPhoneId || undefined,\n businessAccountId: envBusinessId || undefined,\n webhookVerifyToken: envWebhookToken || undefined,\n dmPolicy: envDmPolicy as WhatsAppAccountRuntimeConfig[\"dmPolicy\"] | undefined,\n groupPolicy: envGroupPolicy as WhatsAppAccountRuntimeConfig[\"groupPolicy\"] | undefined,\n };\n\n // Merge order: env defaults < base config < account config\n // Filter undefined values to prevent them from overwriting defined values\n return {\n ...filterDefined(envConfig),\n ...filterDefined(baseConfig),\n ...filterDefined(accountConfig),\n };\n}\n\n/**\n * Resolves a complete WhatsApp account configuration\n */\nexport function resolveWhatsAppAccount(\n runtime: IAgentRuntime,\n accountId?: string | null\n): ResolvedWhatsAppAccount {\n const normalizedAccountId = normalizeAccountId(accountId);\n const multiConfig = getMultiAccountConfig(runtime);\n\n const baseEnabled = multiConfig.enabled !== false;\n const merged = mergeWhatsAppAccountConfig(runtime, normalizedAccountId);\n const accountEnabled = merged.enabled !== false;\n const enabled = baseEnabled && accountEnabled;\n\n const { token, source: tokenSource } = resolveWhatsAppToken(runtime, normalizedAccountId);\n const phoneNumberId = merged.phoneNumberId?.trim() || \"\";\n\n // Determine if this account is actually configured\n const configured = Boolean(token && phoneNumberId);\n\n return {\n accountId: normalizedAccountId,\n enabled,\n name: merged.name?.trim() || undefined,\n accessToken: token,\n phoneNumberId,\n businessAccountId: merged.businessAccountId?.trim() || undefined,\n tokenSource,\n configured,\n config: merged,\n };\n}\n\n/**\n * Lists all enabled WhatsApp accounts\n */\nexport function listEnabledWhatsAppAccounts(runtime: IAgentRuntime): ResolvedWhatsAppAccount[] {\n return listWhatsAppAccountIds(runtime)\n .map((accountId) => resolveWhatsAppAccount(runtime, accountId))\n .filter((account) => account.enabled && account.configured);\n}\n\n/**\n * Checks if multi-account mode is enabled\n */\nexport function isMultiAccountEnabled(runtime: IAgentRuntime): boolean {\n const accounts = listEnabledWhatsAppAccounts(runtime);\n return accounts.length > 1;\n}\n\n/**\n * Resolves group configuration for a specific group\n */\nexport function resolveWhatsAppGroupConfig(\n runtime: IAgentRuntime,\n accountId: string,\n groupId: string\n): WhatsAppGroupRuntimeConfig | undefined {\n const multiConfig = getMultiAccountConfig(runtime);\n const accountConfig = getAccountConfig(runtime, accountId);\n\n // Check account-level groups first\n const accountGroup = accountConfig?.groups?.[groupId];\n if (accountGroup) {\n return accountGroup;\n }\n\n // Fall back to base-level groups\n return multiConfig.groups?.[groupId];\n}\n\n/**\n * Checks if a user is allowed based on policy and allowlist\n */\nexport function isWhatsAppUserAllowed(params: {\n identifier: string;\n accountConfig: WhatsAppAccountRuntimeConfig;\n isGroup: boolean;\n groupId?: string;\n groupConfig?: WhatsAppGroupRuntimeConfig;\n}): boolean {\n const { identifier, accountConfig, isGroup, groupConfig } = params;\n\n if (isGroup) {\n const policy = accountConfig.groupPolicy ?? \"allowlist\";\n if (policy === \"disabled\") {\n return false;\n }\n\n if (policy === \"open\") {\n return true;\n }\n\n // Check group-specific allowlist first\n if (groupConfig?.allowFrom?.length) {\n return groupConfig.allowFrom.some((allowed) => String(allowed) === identifier);\n }\n\n // Check account-level group allowlist\n if (accountConfig.groupAllowFrom?.length) {\n return accountConfig.groupAllowFrom.some((allowed) => String(allowed) === identifier);\n }\n\n return policy !== \"allowlist\";\n }\n\n // DM handling\n const policy = accountConfig.dmPolicy ?? \"pairing\";\n if (policy === \"disabled\") {\n return false;\n }\n\n if (policy === \"open\") {\n return true;\n }\n\n if (policy === \"pairing\") {\n return true;\n }\n\n // Allowlist policy\n if (accountConfig.allowFrom?.length) {\n return accountConfig.allowFrom.some((allowed) => String(allowed) === identifier);\n }\n\n return false;\n}\n\n/**\n * Checks if mention is required in a group\n */\nexport function isWhatsAppMentionRequired(params: {\n accountConfig: WhatsAppAccountRuntimeConfig;\n groupConfig?: WhatsAppGroupRuntimeConfig;\n}): boolean {\n const { groupConfig } = params;\n return groupConfig?.requireMention ?? false;\n}\n\n/**\n * Result of an async WhatsApp access check\n */\nexport interface WhatsAppAccessCheckResult {\n /** Whether the sender is allowed to proceed */\n allowed: boolean;\n /** If not allowed (pairing policy), the pairing code */\n pairingCode?: string;\n /** Whether a new pairing request was created */\n newPairingRequest?: boolean;\n /** Human-readable message to send to the user when blocked */\n replyMessage?: string;\n}\n\n/**\n * Checks if a user is allowed based on policy and allowlist, with async pairing support.\n *\n * For non-pairing policies, this behaves identically to `isWhatsAppUserAllowed`.\n * For the \"pairing\" policy, this actually checks the PairingService allowlist\n * and creates pairing requests when needed.\n *\n * @example\n * ```typescript\n * const result = await checkWhatsAppUserAccess({\n * runtime,\n * identifier: message.from,\n * accountConfig,\n * isGroup: false,\n * metadata: { name: contact.name },\n * });\n *\n * if (!result.allowed) {\n * if (result.replyMessage) {\n * await sendMessage(result.replyMessage);\n * }\n * return; // Block message processing\n * }\n * ```\n */\nexport async function checkWhatsAppUserAccess(params: {\n runtime: IAgentRuntime;\n identifier: string;\n accountConfig: WhatsAppAccountRuntimeConfig;\n isGroup: boolean;\n groupId?: string;\n groupConfig?: WhatsAppGroupRuntimeConfig;\n metadata?: Record<string, string>;\n}): Promise<WhatsAppAccessCheckResult> {\n const { runtime, identifier, accountConfig, isGroup, groupConfig, metadata } = params;\n\n if (isGroup) {\n // Group access - same logic as synchronous version\n const policy = accountConfig.groupPolicy ?? \"allowlist\";\n if (policy === \"disabled\") {\n return { allowed: false };\n }\n\n if (policy === \"open\") {\n return { allowed: true };\n }\n\n // Check group-specific allowlist first\n if (groupConfig?.allowFrom?.length) {\n const allowed = groupConfig.allowFrom.some((a) => String(a) === identifier);\n return { allowed };\n }\n\n // Check account-level group allowlist\n if (accountConfig.groupAllowFrom?.length) {\n const allowed = accountConfig.groupAllowFrom.some((a) => String(a) === identifier);\n return { allowed };\n }\n\n return { allowed: policy !== \"allowlist\" };\n }\n\n // DM handling\n const policy = accountConfig.dmPolicy ?? \"pairing\";\n if (policy === \"disabled\") {\n return { allowed: false };\n }\n\n if (policy === \"open\") {\n return { allowed: true };\n }\n\n if (policy === \"pairing\") {\n // Use the PairingService for actual pairing workflow\n const result: PairingCheckResult = await checkPairingAllowed(runtime, {\n channel: \"whatsapp\",\n senderId: identifier,\n metadata,\n });\n\n return {\n allowed: result.allowed,\n pairingCode: result.pairingCode,\n newPairingRequest: result.newRequest,\n replyMessage: result.replyMessage,\n };\n }\n\n // Allowlist policy - check static allowlist first\n if (accountConfig.allowFrom?.length) {\n const allowed = accountConfig.allowFrom.some((a) => String(a) === identifier);\n if (allowed) {\n return { allowed: true };\n }\n }\n\n // Also check the dynamic pairing allowlist for the allowlist policy\n const inDynamicAllowlist = await isInAllowlist(runtime, \"whatsapp\", identifier);\n return { allowed: inDynamicAllowlist };\n}\n",
19
- "/**\n * WhatsApp text chunk limit\n */\nexport const WHATSAPP_TEXT_CHUNK_LIMIT = 4096;\n\n/**\n * Regex for WhatsApp user JID (e.g., \"41796666864:0@s.whatsapp.net\")\n */\nconst WHATSAPP_USER_JID_RE = /^(\\d+)(?::\\d+)?@s\\.whatsapp\\.net$/i;\n\n/**\n * Regex for WhatsApp LID (e.g., \"123@lid\")\n */\nconst WHATSAPP_LID_RE = /^(\\d+)@lid$/i;\n\n/**\n * Strips WhatsApp target prefixes from a value\n */\nfunction stripWhatsAppTargetPrefixes(value: string): string {\n let candidate = value.trim();\n for (;;) {\n const before = candidate;\n candidate = candidate.replace(/^whatsapp:/i, \"\").trim();\n if (candidate === before) {\n return candidate;\n }\n }\n}\n\n/**\n * Normalizes a phone number to E.164 format\n */\nexport function normalizeE164(input: string): string {\n const stripped = input.replace(/[\\s\\-().]+/g, \"\");\n const digitsOnly = stripped.replace(/[^\\d+]/g, \"\");\n\n if (!digitsOnly) {\n return \"\";\n }\n\n // If it starts with +, keep as-is (already E.164)\n if (digitsOnly.startsWith(\"+\")) {\n return digitsOnly;\n }\n\n // If it starts with 00, replace with +\n if (digitsOnly.startsWith(\"00\")) {\n return `+${digitsOnly.slice(2)}`;\n }\n\n // Assume it's a full number without the +\n if (digitsOnly.length >= 10) {\n return `+${digitsOnly}`;\n }\n\n // Return as-is if too short\n return digitsOnly;\n}\n\n/**\n * Checks if a value is a WhatsApp group JID (e.g., \"123456789-987654321@g.us\")\n */\nexport function isWhatsAppGroupJid(value: string): boolean {\n const candidate = stripWhatsAppTargetPrefixes(value);\n const lower = candidate.toLowerCase();\n if (!lower.endsWith(\"@g.us\")) {\n return false;\n }\n const localPart = candidate.slice(0, candidate.length - \"@g.us\".length);\n if (!localPart || localPart.includes(\"@\")) {\n return false;\n }\n return /^[0-9]+(-[0-9]+)*$/.test(localPart);\n}\n\n/**\n * Checks if a value looks like a WhatsApp user target\n * (e.g., \"41796666864:0@s.whatsapp.net\" or \"123@lid\")\n */\nexport function isWhatsAppUserTarget(value: string): boolean {\n const candidate = stripWhatsAppTargetPrefixes(value);\n return WHATSAPP_USER_JID_RE.test(candidate) || WHATSAPP_LID_RE.test(candidate);\n}\n\n/**\n * Extracts the phone number from a WhatsApp user JID\n * \"41796666864:0@s.whatsapp.net\" -> \"41796666864\"\n * \"123456@lid\" -> \"123456\"\n */\nfunction extractUserJidPhone(jid: string): string | null {\n const userMatch = jid.match(WHATSAPP_USER_JID_RE);\n if (userMatch) {\n return userMatch[1];\n }\n const lidMatch = jid.match(WHATSAPP_LID_RE);\n if (lidMatch) {\n return lidMatch[1];\n }\n return null;\n}\n\n/**\n * Normalizes a WhatsApp target (phone number, user JID, or group JID)\n * Returns null if the target is invalid\n */\nexport function normalizeWhatsAppTarget(value: string): string | null {\n const candidate = stripWhatsAppTargetPrefixes(value);\n if (!candidate) {\n return null;\n }\n\n // Handle group JIDs\n if (isWhatsAppGroupJid(candidate)) {\n const localPart = candidate.slice(0, candidate.length - \"@g.us\".length);\n return `${localPart}@g.us`;\n }\n\n // Handle user JIDs (e.g., \"41796666864:0@s.whatsapp.net\")\n if (isWhatsAppUserTarget(candidate)) {\n const phone = extractUserJidPhone(candidate);\n if (!phone) {\n return null;\n }\n const normalized = normalizeE164(phone);\n return normalized.length > 1 ? normalized : null;\n }\n\n // If the caller passed a JID-ish string that we don't understand, fail fast.\n // Otherwise normalizeE164 would happily treat \"group:120@g.us\" as a phone number.\n if (candidate.includes(\"@\")) {\n return null;\n }\n\n // Treat as a phone number\n const normalized = normalizeE164(candidate);\n return normalized.length > 1 ? normalized : null;\n}\n\n/**\n * Formats a WhatsApp ID for display\n */\nexport function formatWhatsAppId(id: string): string {\n if (isWhatsAppGroupJid(id)) {\n return `group:${id}`;\n }\n const normalized = normalizeWhatsAppTarget(id);\n return normalized || id;\n}\n\n/**\n * Checks if a WhatsApp ID is a group\n */\nexport function isWhatsAppGroup(id: string): boolean {\n return isWhatsAppGroupJid(id);\n}\n\n/**\n * Gets the chat type from a WhatsApp ID\n */\nexport function getWhatsAppChatType(id: string): \"group\" | \"user\" {\n return isWhatsAppGroupJid(id) ? \"group\" : \"user\";\n}\n\n/**\n * Builds a WhatsApp JID from a phone number\n */\nexport function buildWhatsAppUserJid(phoneNumber: string): string {\n const normalized = normalizeE164(phoneNumber);\n const digits = normalized.replace(/^\\+/, \"\");\n return `${digits}@s.whatsapp.net`;\n}\n\n/**\n * Options for text chunking\n */\nexport interface ChunkWhatsAppTextOpts {\n limit?: number;\n}\n\n/**\n * Splits text at the last safe break point within the limit\n */\nfunction splitAtBreakPoint(text: string, limit: number): { chunk: string; remainder: string } {\n if (text.length <= limit) {\n return { chunk: text, remainder: \"\" };\n }\n\n const searchArea = text.slice(0, limit);\n\n // Prefer double newlines (paragraph breaks)\n const doubleNewline = searchArea.lastIndexOf(\"\\n\\n\");\n if (doubleNewline > limit * 0.5) {\n return {\n chunk: text.slice(0, doubleNewline).trimEnd(),\n remainder: text.slice(doubleNewline + 2).trimStart(),\n };\n }\n\n // Try single newlines\n const singleNewline = searchArea.lastIndexOf(\"\\n\");\n if (singleNewline > limit * 0.5) {\n return {\n chunk: text.slice(0, singleNewline).trimEnd(),\n remainder: text.slice(singleNewline + 1).trimStart(),\n };\n }\n\n // Try sentence boundaries\n const sentenceEnd = Math.max(\n searchArea.lastIndexOf(\". \"),\n searchArea.lastIndexOf(\"! \"),\n searchArea.lastIndexOf(\"? \")\n );\n if (sentenceEnd > limit * 0.5) {\n return {\n chunk: text.slice(0, sentenceEnd + 1).trimEnd(),\n remainder: text.slice(sentenceEnd + 2).trimStart(),\n };\n }\n\n // Try word boundaries\n const space = searchArea.lastIndexOf(\" \");\n if (space > limit * 0.5) {\n return {\n chunk: text.slice(0, space).trimEnd(),\n remainder: text.slice(space + 1).trimStart(),\n };\n }\n\n // Hard break at limit\n return {\n chunk: text.slice(0, limit),\n remainder: text.slice(limit),\n };\n}\n\n/**\n * Chunks text for WhatsApp messages\n */\nexport function chunkWhatsAppText(text: string, opts: ChunkWhatsAppTextOpts = {}): string[] {\n const limit = opts.limit ?? WHATSAPP_TEXT_CHUNK_LIMIT;\n\n if (!text?.trim()) {\n return [];\n }\n\n const normalizedText = text.trim();\n if (normalizedText.length <= limit) {\n return [normalizedText];\n }\n\n const chunks: string[] = [];\n let remaining = normalizedText;\n\n while (remaining.length > 0) {\n const { chunk, remainder } = splitAtBreakPoint(remaining, limit);\n if (chunk) {\n chunks.push(chunk);\n }\n remaining = remainder;\n }\n\n return chunks.filter((c) => c.length > 0);\n}\n\n/**\n * Truncates text to a maximum length with ellipsis\n */\nexport function truncateText(text: string, maxLength: number): string {\n if (text.length <= maxLength) {\n return text;\n }\n if (maxLength <= 3) {\n return \"...\".slice(0, maxLength);\n }\n return `${text.slice(0, maxLength - 3)}...`;\n}\n\n/**\n * Resolves the system location string for logging\n */\nexport function resolveWhatsAppSystemLocation(params: {\n chatType: \"group\" | \"user\";\n chatId: string;\n chatName?: string;\n}): string {\n const { chatType, chatId, chatName } = params;\n const name = chatName || chatId.slice(0, 8);\n return `WhatsApp ${chatType}:${name}`;\n}\n\n/**\n * Validates a WhatsApp phone number\n */\nexport function isValidWhatsAppNumber(value: string): boolean {\n const normalized = normalizeWhatsAppTarget(value);\n if (!normalized) {\n return false;\n }\n // Must be E.164 format with at least 10 digits\n if (!normalized.startsWith(\"+\")) {\n return false;\n }\n const digits = normalized.replace(/^\\+/, \"\");\n return /^\\d{10,15}$/.test(digits);\n}\n\n/**\n * Formats a phone number for WhatsApp display\n */\nexport function formatWhatsAppPhoneNumber(phoneNumber: string): string {\n const normalized = normalizeE164(phoneNumber);\n if (!normalized) {\n return phoneNumber;\n }\n // Format as +XX XXX XXX XXXX for display\n const digits = normalized.replace(/^\\+/, \"\");\n if (digits.length <= 10) {\n return normalized;\n }\n // Simple formatting: country code + rest\n const countryCode = digits.slice(0, digits.length - 10);\n const rest = digits.slice(-10);\n return `+${countryCode} ${rest.slice(0, 3)} ${rest.slice(3, 6)} ${rest.slice(6)}`;\n}\n",
20
- "export type WhatsAppConfig = CloudAPIConfig | BaileysConfig;\n\nexport interface CloudAPIConfig {\n authMethod?: \"cloudapi\";\n accessToken: string;\n phoneNumberId: string;\n webhookVerifyToken?: string;\n businessAccountId?: string;\n apiVersion?: string;\n}\n\nexport interface BaileysConfig {\n authMethod?: \"baileys\";\n authDir: string;\n printQRInTerminal?: boolean;\n sessionPath?: string;\n}\n\n/**\n * Message types supported by WhatsApp Cloud API.\n */\nexport type WhatsAppMessageType =\n | \"text\"\n | \"template\"\n | \"image\"\n | \"audio\"\n | \"video\"\n | \"document\"\n | \"sticker\"\n | \"location\"\n | \"contacts\"\n | \"interactive\"\n | \"reaction\";\n\nexport interface WhatsAppMessage {\n type: WhatsAppMessageType;\n to: string;\n content:\n | string\n | WhatsAppTemplate\n | WhatsAppMediaMessage\n | WhatsAppInteractiveMessage\n | WhatsAppReactionMessage\n | WhatsAppLocationMessage;\n replyToMessageId?: string;\n}\n\nexport interface WhatsAppTemplate {\n name: string;\n language: {\n code: string;\n };\n components?: Array<{\n type: string;\n parameters: Array<{\n type: string;\n text?: string;\n image?: { link: string };\n document?: { link: string; filename?: string };\n video?: { link: string };\n }>;\n }>;\n}\n\n/**\n * Media message content.\n */\nexport interface WhatsAppMediaMessage {\n link?: string;\n id?: string;\n caption?: string;\n filename?: string;\n mimeType?: string;\n}\n\n/**\n * Reaction message content.\n */\nexport interface WhatsAppReactionMessage {\n messageId: string;\n emoji: string;\n}\n\n/**\n * Location message content.\n */\nexport interface WhatsAppLocationMessage {\n latitude: number;\n longitude: number;\n name?: string;\n address?: string;\n}\n\n/**\n * Interactive message types.\n */\nexport type InteractiveMessageType = \"button\" | \"list\" | \"product\" | \"product_list\" | \"flow\";\n\n/**\n * Interactive message content.\n */\nexport interface WhatsAppInteractiveMessage {\n type: InteractiveMessageType;\n header?: {\n type: \"text\" | \"image\" | \"video\" | \"document\";\n text?: string;\n image?: { link: string };\n video?: { link: string };\n document?: { link: string; filename?: string };\n };\n body: {\n text: string;\n };\n footer?: {\n text: string;\n };\n action: WhatsAppInteractiveAction;\n}\n\n/**\n * Interactive action based on message type.\n */\nexport type WhatsAppInteractiveAction =\n | WhatsAppButtonAction\n | WhatsAppListAction\n | WhatsAppFlowAction;\n\n/**\n * Button action for interactive messages.\n */\nexport interface WhatsAppButtonAction {\n buttons: Array<{\n type: \"reply\";\n reply: {\n id: string;\n title: string;\n };\n }>;\n}\n\n/**\n * List action for interactive messages.\n */\nexport interface WhatsAppListAction {\n button: string;\n sections: Array<{\n title?: string;\n rows: Array<{\n id: string;\n title: string;\n description?: string;\n }>;\n }>;\n}\n\n/**\n * Flow action for interactive messages.\n */\nexport interface WhatsAppFlowAction {\n name: \"flow\";\n parameters: {\n flow_message_version: string;\n flow_token: string;\n flow_id: string;\n flow_cta: string;\n flow_action: \"navigate\" | \"data_exchange\";\n flow_action_payload?: {\n screen: string;\n data?: Record<string, unknown>;\n };\n };\n}\n\nexport interface WhatsAppIncomingMessage {\n from: string;\n id: string;\n timestamp: string;\n text?: {\n body: string;\n };\n image?: {\n caption?: string;\n mime_type: string;\n sha256: string;\n id: string;\n };\n video?: {\n caption?: string;\n mime_type: string;\n sha256: string;\n id: string;\n };\n audio?: {\n mime_type: string;\n sha256: string;\n id: string;\n voice?: boolean;\n };\n document?: {\n caption?: string;\n filename: string;\n mime_type: string;\n sha256: string;\n id: string;\n };\n sticker?: {\n mime_type: string;\n sha256: string;\n id: string;\n animated?: boolean;\n };\n location?: {\n latitude: number;\n longitude: number;\n name?: string;\n address?: string;\n };\n contacts?: Array<{\n name: {\n formatted_name: string;\n first_name?: string;\n last_name?: string;\n };\n phones?: Array<{\n phone: string;\n type: string;\n }>;\n }>;\n interactive?: {\n type: \"button_reply\" | \"list_reply\" | \"nfm_reply\";\n button_reply?: {\n id: string;\n title: string;\n };\n list_reply?: {\n id: string;\n title: string;\n description?: string;\n };\n nfm_reply?: {\n response_json: string;\n body: string;\n name: string;\n };\n };\n reaction?: {\n message_id: string;\n emoji: string;\n };\n context?: {\n from: string;\n id: string;\n referred_product?: {\n catalog_id: string;\n product_retailer_id: string;\n };\n };\n type: string;\n}\n\nexport interface WhatsAppStatusUpdate {\n id: string;\n status: \"sent\" | \"delivered\" | \"read\" | \"failed\";\n timestamp: string;\n recipient_id: string;\n conversation?: {\n id: string;\n origin?: {\n type: string;\n };\n expiration_timestamp?: string;\n };\n pricing?: {\n billable: boolean;\n pricing_model: string;\n category: string;\n };\n errors?: Array<{\n code: number;\n title: string;\n message?: string;\n error_data?: {\n details: string;\n };\n }>;\n}\n\nexport interface WhatsAppWebhookEvent {\n object: string;\n entry: Array<{\n id: string;\n changes: Array<{\n value: {\n messaging_product: string;\n metadata: {\n display_phone_number: string;\n phone_number_id: string;\n };\n statuses?: WhatsAppStatusUpdate[];\n messages?: WhatsAppIncomingMessage[];\n contacts?: Array<{\n profile: {\n name: string;\n };\n wa_id: string;\n }>;\n errors?: Array<{\n code: number;\n title: string;\n message?: string;\n error_data?: {\n details: string;\n };\n }>;\n };\n field: string;\n }>;\n }>;\n}\n\nexport interface WhatsAppMessageResponse {\n messaging_product: string;\n contacts: Array<{\n input: string;\n wa_id: string;\n }>;\n messages: Array<{\n id: string;\n message_status?: string;\n }>;\n}\n\nexport interface QRCodeData {\n terminal: string;\n dataURL: string;\n raw: string;\n}\n\nexport type ConnectionStatus = \"connecting\" | \"open\" | \"close\";\n\nexport interface UnifiedMessage {\n id: string;\n from: string;\n timestamp: number;\n type: \"text\" | \"image\" | \"audio\" | \"video\" | \"document\";\n content: string;\n}\n\n/**\n * Send reaction parameters.\n */\nexport interface SendReactionParams {\n to: string;\n messageId: string;\n emoji: string;\n}\n\n/**\n * Send reaction result.\n */\nexport interface SendReactionResult {\n success: boolean;\n messageId?: string;\n error?: string;\n}\n\n/**\n * WhatsApp event types.\n */\nexport enum WhatsAppEventType {\n MESSAGE_RECEIVED = \"WHATSAPP_MESSAGE_RECEIVED\",\n MESSAGE_SENT = \"WHATSAPP_MESSAGE_SENT\",\n MESSAGE_DELIVERED = \"WHATSAPP_MESSAGE_DELIVERED\",\n MESSAGE_READ = \"WHATSAPP_MESSAGE_READ\",\n MESSAGE_FAILED = \"WHATSAPP_MESSAGE_FAILED\",\n REACTION_RECEIVED = \"WHATSAPP_REACTION_RECEIVED\",\n REACTION_SENT = \"WHATSAPP_REACTION_SENT\",\n INTERACTIVE_REPLY = \"WHATSAPP_INTERACTIVE_REPLY\",\n WEBHOOK_VERIFIED = \"WHATSAPP_WEBHOOK_VERIFIED\",\n}\n\n/**\n * Common WhatsApp reaction emojis.\n */\nexport const WHATSAPP_REACTIONS = {\n THUMBS_UP: \"👍\",\n THUMBS_DOWN: \"👎\",\n HEART: \"❤️\",\n LAUGHING: \"😂\",\n SURPRISED: \"😮\",\n SAD: \"😢\",\n PRAYING: \"🙏\",\n CLAPPING: \"👏\",\n FIRE: \"🔥\",\n CELEBRATION: \"🎉\",\n} as const;\n\nexport type WhatsAppReactionEmoji = (typeof WHATSAPP_REACTIONS)[keyof typeof WHATSAPP_REACTIONS];\n"
5
+ "import { EventEmitter } from \"node:events\";\nimport type { Plugin } from \"@elizaos/core\";\nimport { sendMessageAction, sendReactionAction } from \"./actions\";\nimport { ClientFactory } from \"./clients/factory\";\nimport type { IWhatsAppClient } from \"./clients/interface\";\nimport { MessageHandler, WebhookHandler } from \"./handlers\";\nimport type {\n\tConnectionStatus,\n\tWhatsAppConfig,\n\tWhatsAppMessage,\n\tWhatsAppMessageResponse,\n\tWhatsAppWebhookEvent,\n} from \"./types\";\n\nexport class WhatsAppPlugin extends EventEmitter implements Plugin {\n\tprivate readonly client: IWhatsAppClient;\n\tprivate readonly messageHandler: MessageHandler;\n\tprivate readonly webhookHandler: WebhookHandler;\n\n\tname: string;\n\tdescription: string;\n\tactions = [sendMessageAction, sendReactionAction];\n\n\tconstructor(config: WhatsAppConfig) {\n\t\tsuper();\n\t\tthis.name = \"WhatsApp Plugin\";\n\t\tthis.description =\n\t\t\t\"WhatsApp integration supporting Cloud API and Baileys (QR auth)\";\n\t\tthis.client = ClientFactory.create(config);\n\t\tthis.messageHandler = new MessageHandler(this.client);\n\t\tthis.webhookHandler = new WebhookHandler();\n\t\tthis.setupEventForwarding();\n\t}\n\n\tprivate setupEventForwarding(): void {\n\t\tthis.client.on(\"message\", (payload) => this.emit(\"message\", payload));\n\t\tthis.client.on(\"qr\", (payload) => this.emit(\"qr\", payload));\n\t\tthis.client.on(\"ready\", () => this.emit(\"ready\"));\n\t\tthis.client.on(\"connection\", (status) => this.emit(\"connection\", status));\n\t\tthis.client.on(\"error\", (error) => this.emit(\"error\", error));\n\t}\n\n\tasync start(): Promise<void> {\n\t\tawait this.client.start();\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tawait this.client.stop();\n\t}\n\n\tgetConnectionStatus(): ConnectionStatus {\n\t\treturn this.client.getConnectionStatus();\n\t}\n\n\tasync sendMessage(\n\t\tmessage: WhatsAppMessage,\n\t): Promise<WhatsAppMessageResponse> {\n\t\treturn this.messageHandler.send(message);\n\t}\n\n\tasync handleWebhook(event: WhatsAppWebhookEvent): Promise<void> {\n\t\treturn this.webhookHandler.handle(event);\n\t}\n\n\tasync verifyWebhook(token: string): Promise<boolean> {\n\t\tif (!this.client.verifyWebhook) {\n\t\t\tthrow new Error(\n\t\t\t\t\"verifyWebhook is only supported by Cloud API authentication\",\n\t\t\t);\n\t\t}\n\t\treturn this.client.verifyWebhook(token);\n\t}\n}\n\nconst whatsappPlugin: Plugin = {\n\tname: \"whatsapp\",\n\tdescription: \"WhatsApp integration for ElizaOS (Cloud API + Baileys)\",\n\tactions: [sendMessageAction, sendReactionAction],\n};\n\nexport default whatsappPlugin;\n\n// Account management exports\nexport {\n\tcheckWhatsAppUserAccess,\n\tDEFAULT_ACCOUNT_ID,\n\tisMultiAccountEnabled,\n\tisWhatsAppMentionRequired,\n\tisWhatsAppUserAllowed,\n\tlistEnabledWhatsAppAccounts,\n\tlistWhatsAppAccountIds,\n\tnormalizeAccountId,\n\ttype ResolvedWhatsAppAccount,\n\tresolveDefaultWhatsAppAccountId,\n\tresolveWhatsAppAccount,\n\tresolveWhatsAppGroupConfig,\n\tresolveWhatsAppToken,\n\ttype WhatsAppAccessCheckResult,\n\ttype WhatsAppAccountRuntimeConfig,\n\ttype WhatsAppGroupRuntimeConfig,\n\ttype WhatsAppMultiAccountConfig,\n\ttype WhatsAppTokenResolution,\n\ttype WhatsAppTokenSource,\n} from \"./accounts\";\nexport { ClientFactory } from \"./clients/factory\";\n// Channel configuration types\nexport type {\n\tWhatsAppAccountConfig,\n\tWhatsAppAckReactionConfig,\n\tWhatsAppActionConfig,\n\tWhatsAppChannelConfig,\n\tWhatsAppGroupConfig,\n} from \"./config\";\n// Normalization and utility exports\nexport {\n\tbuildWhatsAppUserJid,\n\ttype ChunkWhatsAppTextOpts,\n\tchunkWhatsAppText,\n\tformatWhatsAppId,\n\tformatWhatsAppPhoneNumber,\n\tgetWhatsAppChatType,\n\tisValidWhatsAppNumber,\n\tisWhatsAppGroup,\n\tisWhatsAppGroupJid,\n\tisWhatsAppUserTarget,\n\tnormalizeE164,\n\tnormalizeWhatsAppTarget,\n\tresolveWhatsAppSystemLocation,\n\ttruncateText,\n\tWHATSAPP_TEXT_CHUNK_LIMIT,\n} from \"./normalize\";\nexport * from \"./types\";\n",
6
+ "import type {\n\tAction,\n\tActionExample,\n\tActionResult,\n\tHandlerCallback,\n\tHandlerOptions,\n\tIAgentRuntime,\n\tMemory,\n\tState,\n} from \"@elizaos/core\";\nimport {\n\tcomposePromptFromState,\n\tModelType,\n\tparseJSONObjectFromText,\n} from \"@elizaos/core\";\n\nexport const WHATSAPP_SEND_MESSAGE_ACTION = \"WHATSAPP_SEND_MESSAGE\";\n\nconst SEND_MESSAGE_TEMPLATE = `\nYou are extracting WhatsApp message parameters from a conversation.\n\nThe user wants to send a WhatsApp message. Extract the following:\n1. to: The phone number to send to (E.164 format, e.g., +14155552671)\n2. text: The message text to send\n\n{{recentMessages}}\n\nBased on the conversation, extract the message parameters.\n\nRespond with a JSON object:\n{\n \"to\": \"+14155552671\",\n \"text\": \"Hello from WhatsApp!\"\n}\n`;\n\ninterface SendMessageParams {\n\tto: string;\n\ttext: string;\n}\n\nexport const sendMessageAction: Action = {\n\tname: WHATSAPP_SEND_MESSAGE_ACTION,\n\tsimiles: [\n\t\t\"SEND_WHATSAPP\",\n\t\t\"WHATSAPP_MESSAGE\",\n\t\t\"TEXT_WHATSAPP\",\n\t\t\"SEND_WHATSAPP_MESSAGE\",\n\t],\n\tdescription: \"Send a text message via WhatsApp\",\n\n\tvalidate: async (\n\t\truntime: any,\n\t\tmessage: any,\n\t\tstate?: any,\n\t\toptions?: any,\n\t): Promise<boolean> => {\n\t\tconst __avTextRaw =\n\t\t\ttypeof message?.content?.text === \"string\" ? message.content.text : \"\";\n\t\tconst __avText = __avTextRaw.toLowerCase();\n\t\tconst __avKeywords = [\"whatsapp\", \"send\", \"message\"];\n\t\tconst __avKeywordOk =\n\t\t\t__avKeywords.length > 0 &&\n\t\t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n\t\tconst __avRegex = /\\b(?:whatsapp|send|message)\\b/i;\n\t\tconst __avRegexOk = __avRegex.test(__avText);\n\t\tconst __avSource = String(\n\t\t\tmessage?.content?.source ?? message?.source ?? \"\",\n\t\t);\n\t\tconst __avExpectedSource = \"whatsapp\";\n\t\tconst __avSourceOk = __avExpectedSource\n\t\t\t? __avSource === __avExpectedSource\n\t\t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n\t\tconst __avOptions = options && typeof options === \"object\" ? options : {};\n\t\tconst __avInputOk =\n\t\t\t__avText.trim().length > 0 ||\n\t\t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n\t\t\tBoolean(message?.content && typeof message.content === \"object\");\n\n\t\tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst __avLegacyValidate = async (\n\t\t\t_runtime: IAgentRuntime,\n\t\t\tmessage: Memory,\n\t\t): Promise<boolean> => {\n\t\t\tconst source = message.content?.source;\n\t\t\treturn source === \"whatsapp\";\n\t\t};\n\t\ttry {\n\t\t\treturn Boolean(\n\t\t\t\tawait (__avLegacyValidate as any)(runtime, message, state, options),\n\t\t\t);\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t},\n\n\thandler: async (\n\t\truntime: IAgentRuntime,\n\t\tmessage: Memory,\n\t\tstate: State | undefined,\n\t\t_options?: HandlerOptions,\n\t\tcallback?: HandlerCallback,\n\t): Promise<ActionResult> => {\n\t\t// Get WhatsApp settings\n\t\tconst accessToken = runtime.getSetting(\"WHATSAPP_ACCESS_TOKEN\") as string;\n\t\tconst phoneNumberId = runtime.getSetting(\n\t\t\t\"WHATSAPP_PHONE_NUMBER_ID\",\n\t\t) as string;\n\t\tconst apiVersion =\n\t\t\t(runtime.getSetting(\"WHATSAPP_API_VERSION\") as string) || \"v24.0\";\n\n\t\tif (!accessToken || !phoneNumberId) {\n\t\t\tif (callback) {\n\t\t\t\tawait callback({\n\t\t\t\t\ttext: \"WhatsApp is not configured. Missing access token or phone number ID.\",\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { success: false, error: \"WhatsApp not configured\" };\n\t\t}\n\n\t\tconst currentState = state ?? (await runtime.composeState(message));\n\n\t\t// Extract message parameters using LLM\n\t\tconst prompt = composePromptFromState({\n\t\t\tstate: currentState,\n\t\t\ttemplate: SEND_MESSAGE_TEMPLATE,\n\t\t});\n\n\t\tlet params: SendMessageParams;\n\t\ttry {\n\t\t\tconst response = await runtime.useModel(ModelType.TEXT_SMALL, {\n\t\t\t\tprompt,\n\t\t\t});\n\n\t\t\tconst parsed = parseJSONObjectFromText(\n\t\t\t\tresponse,\n\t\t\t) as unknown as SendMessageParams | null;\n\t\t\tif (!parsed || !parsed.to || !parsed.text) {\n\t\t\t\t// Try to use context from message\n\t\t\t\tconst to = message.content?.from as string;\n\t\t\t\tconst text = currentState.values?.response?.toString() || \"\";\n\n\t\t\t\tif (!to) {\n\t\t\t\t\tif (callback) {\n\t\t\t\t\t\tawait callback({\n\t\t\t\t\t\t\ttext: \"Could not determine who to send the message to\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn { success: false, error: \"Missing recipient\" };\n\t\t\t\t}\n\n\t\t\t\t// Validate text is not empty\n\t\t\t\tif (!text || text.trim() === \"\") {\n\t\t\t\t\tif (callback) {\n\t\t\t\t\t\tawait callback({\n\t\t\t\t\t\t\ttext: \"Cannot send an empty message. Please provide message content.\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn { success: false, error: \"Empty message text\" };\n\t\t\t\t}\n\n\t\t\t\tparams = { to, text };\n\t\t\t} else {\n\t\t\t\t// Also validate that parsed text is not empty\n\t\t\t\tif (!parsed.text.trim()) {\n\t\t\t\t\tif (callback) {\n\t\t\t\t\t\tawait callback({\n\t\t\t\t\t\t\ttext: \"Cannot send an empty message. Please provide message content.\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn { success: false, error: \"Empty message text\" };\n\t\t\t\t}\n\t\t\t\tparams = parsed;\n\t\t\t}\n\t\t} catch {\n\t\t\tif (callback) {\n\t\t\t\tawait callback({\n\t\t\t\t\ttext: \"Failed to parse message parameters\",\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { success: false, error: \"Failed to parse message parameters\" };\n\t\t}\n\n\t\t// Send the message via WhatsApp Cloud API\n\t\ttry {\n\t\t\tconst url = `https://graph.facebook.com/${apiVersion}/${phoneNumberId}/messages`;\n\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${accessToken}`,\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tmessaging_product: \"whatsapp\",\n\t\t\t\t\trecipient_type: \"individual\",\n\t\t\t\t\tto: params.to,\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: {\n\t\t\t\t\t\tpreview_url: false,\n\t\t\t\t\t\tbody: params.text,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst errorData = await response.json();\n\t\t\t\tthrow new Error(errorData.error?.message || `HTTP ${response.status}`);\n\t\t\t}\n\n\t\t\tconst data = (await response.json()) as {\n\t\t\t\tmessages: Array<{ id: string }>;\n\t\t\t};\n\t\t\tconst messageId = data.messages?.[0]?.id;\n\n\t\t\tif (callback) {\n\t\t\t\tawait callback({\n\t\t\t\t\ttext: `Message sent to ${params.to}`,\n\t\t\t\t\taction: WHATSAPP_SEND_MESSAGE_ACTION,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\taction: WHATSAPP_SEND_MESSAGE_ACTION,\n\t\t\t\t\tto: params.to,\n\t\t\t\t\tmessageId,\n\t\t\t\t},\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\tif (callback) {\n\t\t\t\tawait callback({\n\t\t\t\t\ttext: `Failed to send WhatsApp message: ${errorMessage}`,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { success: false, error: errorMessage };\n\t\t}\n\t},\n\n\texamples: [\n\t\t[\n\t\t\t{\n\t\t\t\tname: \"{{name1}}\",\n\t\t\t\tcontent: {\n\t\t\t\t\ttext: \"Send a WhatsApp message to +14155552671 saying hello\",\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"{{agentName}}\",\n\t\t\t\tcontent: {\n\t\t\t\t\ttext: \"I'll send that WhatsApp message now.\",\n\t\t\t\t\tactions: [WHATSAPP_SEND_MESSAGE_ACTION],\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t] as ActionExample[][],\n};\n",
7
+ "import type {\n\tAction,\n\tActionExample,\n\tActionResult,\n\tHandlerCallback,\n\tHandlerOptions,\n\tIAgentRuntime,\n\tMemory,\n\tState,\n} from \"@elizaos/core\";\nimport {\n\tcomposePromptFromState,\n\tModelType,\n\tparseJSONObjectFromText,\n} from \"@elizaos/core\";\n\nexport const WHATSAPP_SEND_REACTION_ACTION = \"WHATSAPP_SEND_REACTION\";\n\nconst REACTION_TEMPLATE = `\nYou are extracting WhatsApp reaction parameters from a conversation.\n\nThe user wants to react to a WhatsApp message. Extract the following:\n1. messageId: The ID of the message to react to\n2. emoji: The emoji to use as a reaction\n\n{{recentMessages}}\n\nBased on the conversation, extract the reaction parameters.\n\nRespond with a JSON object:\n{\n \"messageId\": \"wamid.xxx\",\n \"emoji\": \"👍\"\n}\n`;\n\ninterface ReactionParams {\n\tmessageId: string;\n\temoji: string;\n}\n\nexport const sendReactionAction: Action = {\n\tname: WHATSAPP_SEND_REACTION_ACTION,\n\tsimiles: [\"WHATSAPP_REACT\", \"REACT_WHATSAPP\", \"WHATSAPP_EMOJI\"],\n\tdescription: \"Send a reaction emoji to a WhatsApp message\",\n\n\tvalidate: async (\n\t\truntime: any,\n\t\tmessage: any,\n\t\tstate?: any,\n\t\toptions?: any,\n\t): Promise<boolean> => {\n\t\tconst __avTextRaw =\n\t\t\ttypeof message?.content?.text === \"string\" ? message.content.text : \"\";\n\t\tconst __avText = __avTextRaw.toLowerCase();\n\t\tconst __avKeywords = [\"whatsapp\", \"send\", \"reaction\"];\n\t\tconst __avKeywordOk =\n\t\t\t__avKeywords.length > 0 &&\n\t\t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n\t\tconst __avRegex = /\\b(?:whatsapp|send|reaction)\\b/i;\n\t\tconst __avRegexOk = __avRegex.test(__avText);\n\t\tconst __avSource = String(\n\t\t\tmessage?.content?.source ?? message?.source ?? \"\",\n\t\t);\n\t\tconst __avExpectedSource = \"whatsapp\";\n\t\tconst __avSourceOk = __avExpectedSource\n\t\t\t? __avSource === __avExpectedSource\n\t\t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n\t\tconst __avOptions = options && typeof options === \"object\" ? options : {};\n\t\tconst __avInputOk =\n\t\t\t__avText.trim().length > 0 ||\n\t\t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n\t\t\tBoolean(message?.content && typeof message.content === \"object\");\n\n\t\tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst __avLegacyValidate = async (\n\t\t\t_runtime: IAgentRuntime,\n\t\t\tmessage: Memory,\n\t\t): Promise<boolean> => {\n\t\t\tconst source = message.content?.source;\n\t\t\treturn source === \"whatsapp\";\n\t\t};\n\t\ttry {\n\t\t\treturn Boolean(\n\t\t\t\tawait (__avLegacyValidate as any)(runtime, message, state, options),\n\t\t\t);\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t},\n\n\thandler: async (\n\t\truntime: IAgentRuntime,\n\t\tmessage: Memory,\n\t\tstate: State | undefined,\n\t\t_options?: HandlerOptions,\n\t\tcallback?: HandlerCallback,\n\t): Promise<ActionResult> => {\n\t\t// Get WhatsApp settings\n\t\tconst accessToken = runtime.getSetting(\"WHATSAPP_ACCESS_TOKEN\") as string;\n\t\tconst phoneNumberId = runtime.getSetting(\n\t\t\t\"WHATSAPP_PHONE_NUMBER_ID\",\n\t\t) as string;\n\t\tconst apiVersion =\n\t\t\t(runtime.getSetting(\"WHATSAPP_API_VERSION\") as string) || \"v24.0\";\n\n\t\tif (!accessToken || !phoneNumberId) {\n\t\t\tif (callback) {\n\t\t\t\tawait callback({\n\t\t\t\t\ttext: \"WhatsApp is not configured. Missing access token or phone number ID.\",\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { success: false, error: \"WhatsApp not configured\" };\n\t\t}\n\n\t\tconst currentState = state ?? (await runtime.composeState(message));\n\n\t\t// Extract reaction parameters using LLM\n\t\tconst prompt = composePromptFromState({\n\t\t\tstate: currentState,\n\t\t\ttemplate: REACTION_TEMPLATE,\n\t\t});\n\n\t\tlet params: ReactionParams;\n\t\ttry {\n\t\t\tconst response = await runtime.useModel(ModelType.TEXT_SMALL, {\n\t\t\t\tprompt,\n\t\t\t});\n\n\t\t\tconst parsed = parseJSONObjectFromText(\n\t\t\t\tresponse,\n\t\t\t) as unknown as ReactionParams | null;\n\t\t\tif (!parsed || !parsed.messageId || !parsed.emoji) {\n\t\t\t\t// Try to use context from message\n\t\t\t\tconst messageId = message.content?.messageId as string;\n\t\t\t\tif (!messageId) {\n\t\t\t\t\tif (callback) {\n\t\t\t\t\t\tawait callback({\n\t\t\t\t\t\t\ttext: \"Could not determine which message to react to\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn { success: false, error: \"Missing message ID\" };\n\t\t\t\t}\n\t\t\t\tparams = { messageId, emoji: \"👍\" }; // Default to thumbs up\n\t\t\t} else {\n\t\t\t\tparams = parsed;\n\t\t\t}\n\t\t} catch {\n\t\t\tif (callback) {\n\t\t\t\tawait callback({\n\t\t\t\t\ttext: \"Failed to parse reaction parameters\",\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { success: false, error: \"Failed to parse reaction parameters\" };\n\t\t}\n\n\t\t// Get the recipient (sender of the original message)\n\t\tconst to = message.content?.from as string;\n\t\tif (!to) {\n\t\t\tif (callback) {\n\t\t\t\tawait callback({\n\t\t\t\t\ttext: \"Could not determine the recipient for the reaction\",\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { success: false, error: \"Missing recipient\" };\n\t\t}\n\n\t\t// Send the reaction via WhatsApp Cloud API\n\t\ttry {\n\t\t\tconst url = `https://graph.facebook.com/${apiVersion}/${phoneNumberId}/messages`;\n\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${accessToken}`,\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tmessaging_product: \"whatsapp\",\n\t\t\t\t\trecipient_type: \"individual\",\n\t\t\t\t\tto,\n\t\t\t\t\ttype: \"reaction\",\n\t\t\t\t\treaction: {\n\t\t\t\t\t\tmessage_id: params.messageId,\n\t\t\t\t\t\temoji: params.emoji,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst errorData = await response.json();\n\t\t\t\tthrow new Error(errorData.error?.message || `HTTP ${response.status}`);\n\t\t\t}\n\n\t\t\tif (callback) {\n\t\t\t\tawait callback({\n\t\t\t\t\ttext: `Reacted with ${params.emoji}`,\n\t\t\t\t\taction: WHATSAPP_SEND_REACTION_ACTION,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\taction: WHATSAPP_SEND_REACTION_ACTION,\n\t\t\t\t\tmessageId: params.messageId,\n\t\t\t\t\temoji: params.emoji,\n\t\t\t\t},\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\tif (callback) {\n\t\t\t\tawait callback({\n\t\t\t\t\ttext: `Failed to send reaction: ${errorMessage}`,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { success: false, error: errorMessage };\n\t\t}\n\t},\n\n\texamples: [\n\t\t[\n\t\t\t{\n\t\t\t\tname: \"{{name1}}\",\n\t\t\t\tcontent: {\n\t\t\t\t\ttext: \"React with a thumbs up\",\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"{{agentName}}\",\n\t\t\t\tcontent: {\n\t\t\t\t\ttext: \"I'll add that reaction.\",\n\t\t\t\t\tactions: [WHATSAPP_SEND_REACTION_ACTION],\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t] as ActionExample[][],\n};\n",
8
+ "import { EventEmitter } from \"node:events\";\nimport axios, { type AxiosInstance, type AxiosResponse } from \"axios\";\nimport type { IWhatsAppClient } from \"./clients/interface\";\nimport type {\n\tCloudAPIConfig,\n\tConnectionStatus,\n\tSendReactionParams,\n\tSendReactionResult,\n\tWhatsAppInteractiveMessage,\n\tWhatsAppLocationMessage,\n\tWhatsAppMediaMessage,\n\tWhatsAppMessage,\n\tWhatsAppMessageResponse,\n\tWhatsAppReactionMessage,\n} from \"./types\";\n\nconst DEFAULT_API_VERSION = \"v24.0\";\n\nexport class WhatsAppClient extends EventEmitter implements IWhatsAppClient {\n\tprivate client: AxiosInstance;\n\tprivate config: CloudAPIConfig;\n\tprivate connectionStatus: ConnectionStatus = \"close\";\n\n\tconstructor(config: CloudAPIConfig) {\n\t\tsuper();\n\t\tthis.config = config;\n\t\tconst apiVersion = config.apiVersion || DEFAULT_API_VERSION;\n\n\t\tthis.client = axios.create({\n\t\t\tbaseURL: `https://graph.facebook.com/${apiVersion}`,\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${config.accessToken}`,\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t});\n\t}\n\n\tasync start(): Promise<void> {\n\t\tthis.connectionStatus = \"open\";\n\t\tthis.emit(\"connection\", \"open\");\n\t\tthis.emit(\"ready\");\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tthis.connectionStatus = \"close\";\n\t\tthis.emit(\"connection\", \"close\");\n\t}\n\n\tgetConnectionStatus(): ConnectionStatus {\n\t\treturn this.connectionStatus;\n\t}\n\n\t/**\n\t * Get the configured phone number ID.\n\t */\n\tgetPhoneNumberId(): string {\n\t\treturn this.config.phoneNumberId;\n\t}\n\n\t/**\n\t * Send a message of any supported type.\n\t */\n\tasync sendMessage(\n\t\tmessage: WhatsAppMessage,\n\t): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n\t\tconst endpoint = `/${this.config.phoneNumberId}/messages`;\n\t\tconst payload = this.buildMessagePayload(message);\n\t\treturn this.client.post(endpoint, payload);\n\t}\n\n\t/**\n\t * Send a text message.\n\t */\n\tasync sendTextMessage(\n\t\tto: string,\n\t\ttext: string,\n\t\t_previewUrl = false,\n\t): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n\t\treturn this.sendMessage({\n\t\t\ttype: \"text\",\n\t\t\tto,\n\t\t\tcontent: text,\n\t\t});\n\t}\n\n\t/**\n\t * Send a reaction to a message.\n\t */\n\tasync sendReaction(params: SendReactionParams): Promise<SendReactionResult> {\n\t\tconst endpoint = `/${this.config.phoneNumberId}/messages`;\n\n\t\tconst payload = {\n\t\t\tmessaging_product: \"whatsapp\",\n\t\t\trecipient_type: \"individual\",\n\t\t\tto: params.to,\n\t\t\ttype: \"reaction\",\n\t\t\treaction: {\n\t\t\t\tmessage_id: params.messageId,\n\t\t\t\temoji: params.emoji,\n\t\t\t},\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this.client.post<WhatsAppMessageResponse>(\n\t\t\t\tendpoint,\n\t\t\t\tpayload,\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessageId: response.data.messages?.[0]?.id,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: errorMessage,\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Remove a reaction from a message (send empty emoji).\n\t */\n\tasync removeReaction(\n\t\tto: string,\n\t\tmessageId: string,\n\t): Promise<SendReactionResult> {\n\t\treturn this.sendReaction({\n\t\t\tto,\n\t\t\tmessageId,\n\t\t\temoji: \"\",\n\t\t});\n\t}\n\n\t/**\n\t * Send an image message.\n\t */\n\tasync sendImage(\n\t\tto: string,\n\t\timageUrl: string,\n\t\tcaption?: string,\n\t): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n\t\treturn this.sendMessage({\n\t\t\ttype: \"image\",\n\t\t\tto,\n\t\t\tcontent: {\n\t\t\t\tlink: imageUrl,\n\t\t\t\tcaption,\n\t\t\t} as WhatsAppMediaMessage,\n\t\t});\n\t}\n\n\t/**\n\t * Send a video message.\n\t */\n\tasync sendVideo(\n\t\tto: string,\n\t\tvideoUrl: string,\n\t\tcaption?: string,\n\t): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n\t\treturn this.sendMessage({\n\t\t\ttype: \"video\",\n\t\t\tto,\n\t\t\tcontent: {\n\t\t\t\tlink: videoUrl,\n\t\t\t\tcaption,\n\t\t\t} as WhatsAppMediaMessage,\n\t\t});\n\t}\n\n\t/**\n\t * Send an audio message.\n\t */\n\tasync sendAudio(\n\t\tto: string,\n\t\taudioUrl: string,\n\t): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n\t\treturn this.sendMessage({\n\t\t\ttype: \"audio\",\n\t\t\tto,\n\t\t\tcontent: {\n\t\t\t\tlink: audioUrl,\n\t\t\t} as WhatsAppMediaMessage,\n\t\t});\n\t}\n\n\t/**\n\t * Send a document message.\n\t */\n\tasync sendDocument(\n\t\tto: string,\n\t\tdocumentUrl: string,\n\t\tfilename?: string,\n\t\tcaption?: string,\n\t): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n\t\treturn this.sendMessage({\n\t\t\ttype: \"document\",\n\t\t\tto,\n\t\t\tcontent: {\n\t\t\t\tlink: documentUrl,\n\t\t\t\tfilename,\n\t\t\t\tcaption,\n\t\t\t} as WhatsAppMediaMessage,\n\t\t});\n\t}\n\n\t/**\n\t * Send a location message.\n\t */\n\tasync sendLocation(\n\t\tto: string,\n\t\tlatitude: number,\n\t\tlongitude: number,\n\t\tname?: string,\n\t\taddress?: string,\n\t): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n\t\treturn this.sendMessage({\n\t\t\ttype: \"location\",\n\t\t\tto,\n\t\t\tcontent: {\n\t\t\t\tlatitude,\n\t\t\t\tlongitude,\n\t\t\t\tname,\n\t\t\t\taddress,\n\t\t\t} as WhatsAppLocationMessage,\n\t\t});\n\t}\n\n\t/**\n\t * Send an interactive button message.\n\t */\n\tasync sendButtonMessage(\n\t\tto: string,\n\t\tbodyText: string,\n\t\tbuttons: Array<{ id: string; title: string }>,\n\t\theaderText?: string,\n\t\tfooterText?: string,\n\t): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n\t\tconst interactive: WhatsAppInteractiveMessage = {\n\t\t\ttype: \"button\",\n\t\t\tbody: { text: bodyText },\n\t\t\taction: {\n\t\t\t\tbuttons: buttons.map((btn) => ({\n\t\t\t\t\ttype: \"reply\" as const,\n\t\t\t\t\treply: { id: btn.id, title: btn.title },\n\t\t\t\t})),\n\t\t\t},\n\t\t};\n\n\t\tif (headerText) {\n\t\t\tinteractive.header = { type: \"text\", text: headerText };\n\t\t}\n\t\tif (footerText) {\n\t\t\tinteractive.footer = { text: footerText };\n\t\t}\n\n\t\treturn this.sendMessage({\n\t\t\ttype: \"interactive\",\n\t\t\tto,\n\t\t\tcontent: interactive,\n\t\t});\n\t}\n\n\t/**\n\t * Send an interactive list message.\n\t */\n\tasync sendListMessage(\n\t\tto: string,\n\t\tbodyText: string,\n\t\tbuttonText: string,\n\t\tsections: Array<{\n\t\t\ttitle?: string;\n\t\t\trows: Array<{ id: string; title: string; description?: string }>;\n\t\t}>,\n\t\theaderText?: string,\n\t\tfooterText?: string,\n\t): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n\t\tconst interactive: WhatsAppInteractiveMessage = {\n\t\t\ttype: \"list\",\n\t\t\tbody: { text: bodyText },\n\t\t\taction: {\n\t\t\t\tbutton: buttonText,\n\t\t\t\tsections,\n\t\t\t},\n\t\t};\n\n\t\tif (headerText) {\n\t\t\tinteractive.header = { type: \"text\", text: headerText };\n\t\t}\n\t\tif (footerText) {\n\t\t\tinteractive.footer = { text: footerText };\n\t\t}\n\n\t\treturn this.sendMessage({\n\t\t\ttype: \"interactive\",\n\t\t\tto,\n\t\t\tcontent: interactive,\n\t\t});\n\t}\n\n\t/**\n\t * Mark a message as read.\n\t */\n\tasync markMessageAsRead(messageId: string): Promise<boolean> {\n\t\tconst endpoint = `/${this.config.phoneNumberId}/messages`;\n\n\t\tconst payload = {\n\t\t\tmessaging_product: \"whatsapp\",\n\t\t\tstatus: \"read\",\n\t\t\tmessage_id: messageId,\n\t\t};\n\n\t\ttry {\n\t\t\tawait this.client.post(endpoint, payload);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Download media by ID.\n\t */\n\tasync getMediaUrl(mediaId: string): Promise<string | null> {\n\t\ttry {\n\t\t\tconst response = await this.client.get(`/${mediaId}`);\n\t\t\treturn response.data.url || null;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Verify webhook token.\n\t */\n\tasync verifyWebhook(token: string): Promise<boolean> {\n\t\treturn token === this.config.webhookVerifyToken;\n\t}\n\n\t/**\n\t * Build the message payload based on message type.\n\t */\n\tprivate buildMessagePayload(\n\t\tmessage: WhatsAppMessage,\n\t): Record<string, unknown> {\n\t\tconst basePayload = {\n\t\t\tmessaging_product: \"whatsapp\",\n\t\t\trecipient_type: \"individual\",\n\t\t\tto: message.to,\n\t\t\ttype: message.type,\n\t\t};\n\n\t\t// Add context for replies\n\t\tconst contextPayload = message.replyToMessageId\n\t\t\t? { context: { message_id: message.replyToMessageId } }\n\t\t\t: {};\n\n\t\tswitch (message.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn {\n\t\t\t\t\t...basePayload,\n\t\t\t\t\t...contextPayload,\n\t\t\t\t\ttext: {\n\t\t\t\t\t\tbody: message.content as string,\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\tcase \"template\":\n\t\t\t\treturn {\n\t\t\t\t\t...basePayload,\n\t\t\t\t\t...contextPayload,\n\t\t\t\t\ttemplate: message.content,\n\t\t\t\t};\n\n\t\t\tcase \"image\": {\n\t\t\t\tconst imageContent = message.content as WhatsAppMediaMessage;\n\t\t\t\treturn {\n\t\t\t\t\t...basePayload,\n\t\t\t\t\t...contextPayload,\n\t\t\t\t\timage: {\n\t\t\t\t\t\tlink: imageContent.link,\n\t\t\t\t\t\tcaption: imageContent.caption,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"video\": {\n\t\t\t\tconst videoContent = message.content as WhatsAppMediaMessage;\n\t\t\t\treturn {\n\t\t\t\t\t...basePayload,\n\t\t\t\t\t...contextPayload,\n\t\t\t\t\tvideo: {\n\t\t\t\t\t\tlink: videoContent.link,\n\t\t\t\t\t\tcaption: videoContent.caption,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"audio\": {\n\t\t\t\tconst audioContent = message.content as WhatsAppMediaMessage;\n\t\t\t\treturn {\n\t\t\t\t\t...basePayload,\n\t\t\t\t\t...contextPayload,\n\t\t\t\t\taudio: {\n\t\t\t\t\t\tlink: audioContent.link,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"document\": {\n\t\t\t\tconst docContent = message.content as WhatsAppMediaMessage;\n\t\t\t\treturn {\n\t\t\t\t\t...basePayload,\n\t\t\t\t\t...contextPayload,\n\t\t\t\t\tdocument: {\n\t\t\t\t\t\tlink: docContent.link,\n\t\t\t\t\t\tfilename: docContent.filename,\n\t\t\t\t\t\tcaption: docContent.caption,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"location\": {\n\t\t\t\tconst locContent = message.content as WhatsAppLocationMessage;\n\t\t\t\treturn {\n\t\t\t\t\t...basePayload,\n\t\t\t\t\t...contextPayload,\n\t\t\t\t\tlocation: {\n\t\t\t\t\t\tlatitude: locContent.latitude,\n\t\t\t\t\t\tlongitude: locContent.longitude,\n\t\t\t\t\t\tname: locContent.name,\n\t\t\t\t\t\taddress: locContent.address,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"reaction\": {\n\t\t\t\tconst reactionContent = message.content as WhatsAppReactionMessage;\n\t\t\t\treturn {\n\t\t\t\t\t...basePayload,\n\t\t\t\t\treaction: {\n\t\t\t\t\t\tmessage_id: reactionContent.messageId,\n\t\t\t\t\t\temoji: reactionContent.emoji,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"interactive\": {\n\t\t\t\tconst interactiveContent =\n\t\t\t\t\tmessage.content as WhatsAppInteractiveMessage;\n\t\t\t\treturn {\n\t\t\t\t\t...basePayload,\n\t\t\t\t\t...contextPayload,\n\t\t\t\t\tinteractive: interactiveContent,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\treturn basePayload;\n\t\t}\n\t}\n}\n",
9
+ "import type { WhatsAppConfig } from \"../types\";\n\nexport function detectAuthMethod(\n\tconfig: WhatsAppConfig | Record<string, unknown>,\n): \"baileys\" | \"cloudapi\" {\n\tconst explicitMethod = (config as { authMethod?: unknown }).authMethod;\n\tif (explicitMethod !== undefined) {\n\t\tif (explicitMethod === \"baileys\" || explicitMethod === \"cloudapi\") {\n\t\t\treturn explicitMethod;\n\t\t}\n\t\tthrow new Error(\n\t\t\t`Invalid authMethod: \"${String(explicitMethod)}\". Must be either \"baileys\" or \"cloudapi\".`,\n\t\t);\n\t}\n\n\tif (\"authDir\" in config && config.authDir) {\n\t\treturn \"baileys\";\n\t}\n\n\tif (\"accessToken\" in config && \"phoneNumberId\" in config) {\n\t\treturn \"cloudapi\";\n\t}\n\n\tthrow new Error(\n\t\t\"Cannot detect auth method. Provide either authDir (Baileys) or accessToken + phoneNumberId (Cloud API).\",\n\t);\n}\n",
10
+ "import { EventEmitter } from \"node:events\";\nimport { BaileysAuthManager } from \"../baileys/auth\";\nimport { BaileysConnection } from \"../baileys/connection\";\nimport { MessageAdapter } from \"../baileys/message-adapter\";\nimport { QRCodeGenerator } from \"../baileys/qr-code\";\nimport type {\n\tBaileysConfig,\n\tConnectionStatus,\n\tWhatsAppMessage,\n\tWhatsAppMessageResponse,\n} from \"../types\";\nimport type { IWhatsAppClient } from \"./interface\";\n\nexport class BaileysClient extends EventEmitter implements IWhatsAppClient {\n\tprivate readonly config: BaileysConfig;\n\tprivate readonly authManager: BaileysAuthManager;\n\tprivate readonly connection: BaileysConnection;\n\tprivate readonly qrGenerator: QRCodeGenerator;\n\tprivate readonly adapter: MessageAdapter;\n\n\tconstructor(config: BaileysConfig) {\n\t\tsuper();\n\t\tthis.config = config;\n\t\tthis.authManager = new BaileysAuthManager(config.authDir);\n\t\tthis.connection = new BaileysConnection(this.authManager);\n\t\tthis.qrGenerator = new QRCodeGenerator();\n\t\tthis.adapter = new MessageAdapter();\n\t\tthis.setupEventForwarding();\n\t}\n\n\tprivate setupEventForwarding(): void {\n\t\tthis.connection.on(\"qr\", async (qr: string) => {\n\t\t\ttry {\n\t\t\t\tconst qrData = await this.qrGenerator.generate(qr);\n\t\t\t\tif (this.config.printQRInTerminal !== false) {\n\t\t\t\t\tconsole.log(\"\\n=== Scan QR Code ===\\n\");\n\t\t\t\t\tconsole.log(qrData.terminal);\n\t\t\t\t}\n\t\t\t\tthis.emit(\"qr\", qrData);\n\t\t\t} catch (error) {\n\t\t\t\tthis.emit(\"error\", error);\n\t\t\t}\n\t\t});\n\n\t\tthis.connection.on(\"connection\", (status: ConnectionStatus) => {\n\t\t\tthis.emit(\"connection\", status);\n\t\t\tif (status === \"open\") {\n\t\t\t\tthis.emit(\"ready\");\n\t\t\t}\n\t\t});\n\n\t\tthis.connection.on(\"messages\", (messages: unknown[]) => {\n\t\t\tfor (const message of messages) {\n\t\t\t\tconst maybe = message as {\n\t\t\t\t\tkey?: { fromMe?: boolean };\n\t\t\t\t\tmessage?: unknown;\n\t\t\t\t};\n\t\t\t\tif (!maybe.key?.fromMe && maybe.message) {\n\t\t\t\t\tthis.emit(\"message\", this.adapter.toUnified(message as any));\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.connection.on(\"error\", (error: unknown) => {\n\t\t\tthis.emit(\"error\", error);\n\t\t});\n\t}\n\n\tasync start(): Promise<void> {\n\t\tawait this.connection.connect();\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tawait this.connection.disconnect();\n\t}\n\n\tasync sendMessage(\n\t\tmessage: WhatsAppMessage,\n\t): Promise<WhatsAppMessageResponse> {\n\t\tconst socket = this.connection.getSocket();\n\t\tif (!socket) {\n\t\t\tthrow new Error(\"Not connected to WhatsApp via Baileys\");\n\t\t}\n\n\t\tconst payload = this.adapter.toBaileys(message);\n\t\tconst result = await socket.sendMessage(message.to, payload as any);\n\t\tconst id = result?.key?.id ?? \"\";\n\n\t\treturn {\n\t\t\tmessaging_product: \"whatsapp\",\n\t\t\tcontacts: [{ input: message.to, wa_id: message.to }],\n\t\t\tmessages: [{ id }],\n\t\t};\n\t}\n\n\tgetConnectionStatus(): ConnectionStatus {\n\t\treturn this.connection.getStatus();\n\t}\n}\n",
11
+ "import type { AuthenticationState } from \"@whiskeysockets/baileys\";\nimport { useMultiFileAuthState } from \"@whiskeysockets/baileys\";\n\nexport class BaileysAuthManager {\n\tprivate readonly authDir: string;\n\tprivate state?: AuthenticationState;\n\tprivate saveCreds?: () => Promise<void>;\n\n\tconstructor(authDir: string) {\n\t\tthis.authDir = authDir;\n\t}\n\n\tasync initialize(): Promise<AuthenticationState> {\n\t\tconst result = await useMultiFileAuthState(this.authDir);\n\t\tthis.state = result.state;\n\t\tthis.saveCreds = result.saveCreds;\n\t\treturn this.state;\n\t}\n\n\tasync save(): Promise<void> {\n\t\tif (this.saveCreds) {\n\t\t\tawait this.saveCreds();\n\t\t}\n\t}\n}\n",
12
+ "import { EventEmitter } from \"node:events\";\nimport type { Boom } from \"@hapi/boom\";\nimport makeWASocket, {\n\tDisconnectReason,\n\ttype WASocket,\n} from \"@whiskeysockets/baileys\";\nimport pino from \"pino\";\nimport type { ConnectionStatus } from \"../types\";\nimport type { BaileysAuthManager } from \"./auth\";\n\nexport class BaileysConnection extends EventEmitter {\n\tprivate socket?: WASocket;\n\tprivate readonly authManager: BaileysAuthManager;\n\tprivate connectionStatus: ConnectionStatus = \"close\";\n\tprivate reconnecting = false;\n\tprivate reconnectAttempts = 0;\n\tprivate readonly maxReconnectAttempts = 10;\n\n\tconstructor(authManager: BaileysAuthManager) {\n\t\tsuper();\n\t\tthis.authManager = authManager;\n\t}\n\n\tasync connect(): Promise<WASocket> {\n\t\tthis.connectionStatus = \"connecting\";\n\t\tthis.emit(\"connection\", \"connecting\");\n\n\t\tconst state = await this.authManager.initialize();\n\t\tthis.socket = makeWASocket({\n\t\t\tauth: state,\n\t\t\tprintQRInTerminal: false,\n\t\t\tlogger: pino({ level: \"silent\" }),\n\t\t\tbrowser: [\"Chrome (Linux)\", \"\", \"\"],\n\t\t});\n\n\t\tthis.setupEventHandlers();\n\t\treturn this.socket;\n\t}\n\n\tprivate setupEventHandlers(): void {\n\t\tif (!this.socket) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.socket.ev.on(\"connection.update\", async (update) => {\n\t\t\tconst { connection, qr, lastDisconnect } = update;\n\n\t\t\tif (qr) {\n\t\t\t\tthis.emit(\"qr\", qr);\n\t\t\t}\n\n\t\t\tif (connection) {\n\t\t\t\tthis.connectionStatus = connection;\n\t\t\t\tthis.emit(\"connection\", connection);\n\t\t\t}\n\n\t\t\tif (connection === \"open\") {\n\t\t\t\tthis.reconnectAttempts = 0;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (connection !== \"close\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst statusCode = (lastDisconnect?.error as Boom | undefined)?.output\n\t\t\t\t?.statusCode;\n\t\t\tconst isQRTimeout = statusCode === 515;\n\t\t\tconst shouldReconnect =\n\t\t\t\tstatusCode !== DisconnectReason.loggedOut && statusCode !== 405;\n\n\t\t\tif (lastDisconnect?.error && !isQRTimeout) {\n\t\t\t\tthis.emit(\"error\", lastDisconnect.error);\n\t\t\t}\n\n\t\t\tif (!shouldReconnect) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.reconnecting) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.reconnectAttempts >= this.maxReconnectAttempts) {\n\t\t\t\tthis.emit(\"error\", new Error(\"Max reconnection attempts reached\"));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.reconnecting = true;\n\t\t\ttry {\n\t\t\t\tthis.reconnectAttempts += 1;\n\t\t\t\tconst baseDelayMs = isQRTimeout ? 1000 : 3000;\n\t\t\t\tconst backoffMs = Math.min(\n\t\t\t\t\tbaseDelayMs * 2 ** (this.reconnectAttempts - 1),\n\t\t\t\t\t30000,\n\t\t\t\t);\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, backoffMs));\n\t\t\t\tawait this.connect();\n\t\t\t} catch (error) {\n\t\t\t\tthis.emit(\"error\", error);\n\t\t\t} finally {\n\t\t\t\tthis.reconnecting = false;\n\t\t\t}\n\t\t});\n\n\t\tthis.socket.ev.on(\"creds.update\", async () => {\n\t\t\tawait this.authManager.save();\n\t\t});\n\n\t\tthis.socket.ev.on(\"messages.upsert\", ({ messages }) => {\n\t\t\tthis.emit(\"messages\", messages);\n\t\t});\n\t}\n\n\tgetSocket(): WASocket | undefined {\n\t\treturn this.socket;\n\t}\n\n\tgetStatus(): ConnectionStatus {\n\t\treturn this.connectionStatus;\n\t}\n\n\tasync disconnect(): Promise<void> {\n\t\tif (!this.socket) {\n\t\t\treturn;\n\t\t}\n\n\t\t(\n\t\t\tthis.socket.ev as unknown as {\n\t\t\t\tremoveAllListeners: (...args: unknown[]) => void;\n\t\t\t}\n\t\t).removeAllListeners();\n\t\t(this.socket as unknown as { ws?: { close?: () => void } }).ws?.close?.();\n\t\tthis.socket = undefined;\n\t\tthis.connectionStatus = \"close\";\n\t\tthis.emit(\"connection\", \"close\");\n\t}\n}\n",
13
+ "import type { proto } from \"@whiskeysockets/baileys\";\nimport type {\n\tUnifiedMessage,\n\tWhatsAppMediaMessage,\n\tWhatsAppMessage,\n\tWhatsAppTemplate,\n} from \"../types\";\n\nexport class MessageAdapter {\n\ttoUnified(msg: proto.IWebMessageInfo): UnifiedMessage {\n\t\treturn {\n\t\t\tid: msg.key?.id ?? \"\",\n\t\t\tfrom: msg.key?.remoteJid ?? \"\",\n\t\t\ttimestamp: Number(msg.messageTimestamp ?? 0),\n\t\t\ttype: this.detectType(msg),\n\t\t\tcontent: this.extractContent(msg),\n\t\t};\n\t}\n\n\ttoBaileys(msg: WhatsAppMessage): Record<string, unknown> {\n\t\tswitch (msg.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn { text: msg.content as string };\n\t\t\tcase \"image\":\n\t\t\t\treturn this.mediaWithCaption(\n\t\t\t\t\t\"image\",\n\t\t\t\t\tmsg.content as WhatsAppMediaMessage,\n\t\t\t\t);\n\t\t\tcase \"video\":\n\t\t\t\treturn this.mediaWithCaption(\n\t\t\t\t\t\"video\",\n\t\t\t\t\tmsg.content as WhatsAppMediaMessage,\n\t\t\t\t);\n\t\t\tcase \"audio\":\n\t\t\t\treturn this.mediaNoCaption(\n\t\t\t\t\t\"audio\",\n\t\t\t\t\tmsg.content as WhatsAppMediaMessage,\n\t\t\t\t);\n\t\t\tcase \"document\":\n\t\t\t\treturn this.mediaWithFilename(msg.content as WhatsAppMediaMessage);\n\t\t\tcase \"template\":\n\t\t\t\treturn { text: this.renderTemplate(msg.content as WhatsAppTemplate) };\n\t\t\tdefault:\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Message type ${msg.type} is not yet supported for Baileys`,\n\t\t\t\t);\n\t\t}\n\t}\n\n\tprivate mediaWithCaption(\n\t\tkey: \"image\" | \"video\",\n\t\tmedia: WhatsAppMediaMessage,\n\t): Record<string, unknown> {\n\t\tif (!media?.link) {\n\t\t\tthrow new Error(`${key} message requires a media link`);\n\t\t}\n\t\treturn {\n\t\t\t[key]: { url: media.link },\n\t\t\t...(media.caption ? { caption: media.caption } : {}),\n\t\t};\n\t}\n\n\tprivate mediaNoCaption(\n\t\tkey: \"audio\",\n\t\tmedia: WhatsAppMediaMessage,\n\t): Record<string, unknown> {\n\t\tif (!media?.link) {\n\t\t\tthrow new Error(`${key} message requires a media link`);\n\t\t}\n\t\treturn { [key]: { url: media.link } };\n\t}\n\n\tprivate mediaWithFilename(\n\t\tmedia: WhatsAppMediaMessage,\n\t): Record<string, unknown> {\n\t\tif (!media?.link) {\n\t\t\tthrow new Error(\"document message requires a media link\");\n\t\t}\n\t\treturn {\n\t\t\tdocument: { url: media.link },\n\t\t\t...(media.filename ? { fileName: media.filename } : {}),\n\t\t\t...(media.caption ? { caption: media.caption } : {}),\n\t\t};\n\t}\n\n\tprivate detectType(\n\t\tmsg: proto.IWebMessageInfo,\n\t): \"text\" | \"image\" | \"audio\" | \"video\" | \"document\" {\n\t\tif (msg.message?.conversation || msg.message?.extendedTextMessage) {\n\t\t\treturn \"text\";\n\t\t}\n\t\tif (msg.message?.imageMessage) {\n\t\t\treturn \"image\";\n\t\t}\n\t\tif (msg.message?.audioMessage) {\n\t\t\treturn \"audio\";\n\t\t}\n\t\tif (msg.message?.videoMessage) {\n\t\t\treturn \"video\";\n\t\t}\n\t\tif (msg.message?.documentMessage) {\n\t\t\treturn \"document\";\n\t\t}\n\t\treturn \"text\";\n\t}\n\n\tprivate extractContent(msg: proto.IWebMessageInfo): string {\n\t\treturn (\n\t\t\tmsg.message?.conversation ?? msg.message?.extendedTextMessage?.text ?? \"\"\n\t\t);\n\t}\n\n\tprivate renderTemplate(template: WhatsAppTemplate): string {\n\t\tconst params = template.components?.flatMap((component) =>\n\t\t\tcomponent.parameters.map((parameter) => parameter.text).filter(Boolean),\n\t\t);\n\t\treturn params && params.length > 0\n\t\t\t? `${template.name}: ${params.join(\", \")}`\n\t\t\t: template.name;\n\t}\n}\n",
14
+ "import QRCode from \"qrcode\";\nimport QRCodeTerminal from \"qrcode-terminal\";\nimport type { QRCodeData } from \"../types\";\n\nexport class QRCodeGenerator {\n\tasync generate(qrString: string): Promise<QRCodeData> {\n\t\treturn {\n\t\t\tterminal: await this.generateTerminal(qrString),\n\t\t\tdataURL: await QRCode.toDataURL(qrString),\n\t\t\traw: qrString,\n\t\t};\n\t}\n\n\tprivate async generateTerminal(qr: string): Promise<string> {\n\t\treturn new Promise((resolve) => {\n\t\t\tQRCodeTerminal.generate(qr, { small: true }, (output: string) => {\n\t\t\t\tresolve(output);\n\t\t\t});\n\t\t});\n\t}\n}\n",
15
+ "import { WhatsAppClient } from \"../client\";\nimport type { BaileysConfig, CloudAPIConfig, WhatsAppConfig } from \"../types\";\nimport { detectAuthMethod } from \"../utils/config-detector\";\nimport { BaileysClient } from \"./baileys-client\";\nimport type { IWhatsAppClient } from \"./interface\";\n\nexport class ClientFactory {\n\tstatic create(config: WhatsAppConfig): IWhatsAppClient {\n\t\tconst authMethod = detectAuthMethod(config);\n\t\tif (authMethod === \"baileys\") {\n\t\t\treturn new BaileysClient(config as BaileysConfig);\n\t\t}\n\t\treturn new WhatsAppClient(config as CloudAPIConfig);\n\t}\n}\n",
16
+ "import type { IWhatsAppClient } from \"../clients/interface\";\nimport type { WhatsAppMessage, WhatsAppMessageResponse } from \"../types\";\n\nexport class MessageHandler {\n\tconstructor(private client: IWhatsAppClient) {}\n\n\tasync send(message: WhatsAppMessage): Promise<WhatsAppMessageResponse> {\n\t\ttry {\n\t\t\tconst response = await this.client.sendMessage(message);\n\t\t\tif (response && typeof response === \"object\" && \"data\" in response) {\n\t\t\t\treturn (response as { data: WhatsAppMessageResponse }).data;\n\t\t\t}\n\t\t\treturn response as WhatsAppMessageResponse;\n\t\t} catch (error: unknown) {\n\t\t\tif (error instanceof Error) {\n\t\t\t\tthrow new Error(`Failed to send WhatsApp message: ${error.message}`);\n\t\t\t}\n\t\t\tthrow new Error(\"Failed to send WhatsApp message\");\n\t\t}\n\t}\n}\n",
17
+ "import type {\n\tWhatsAppIncomingMessage,\n\tWhatsAppStatusUpdate,\n\tWhatsAppWebhookEvent,\n} from \"../types\";\n\nexport class WebhookHandler {\n\tasync handle(event: WhatsAppWebhookEvent): Promise<void> {\n\t\ttry {\n\t\t\t// Process messages\n\t\t\tif (event.entry?.[0]?.changes?.[0]?.value?.messages) {\n\t\t\t\tconst messages = event.entry[0].changes[0].value.messages;\n\t\t\t\tfor (const message of messages) {\n\t\t\t\t\tawait this.handleMessage(message);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Process status updates\n\t\t\tif (event.entry?.[0]?.changes?.[0]?.value?.statuses) {\n\t\t\t\tconst statuses = event.entry[0].changes[0].value.statuses;\n\t\t\t\tfor (const status of statuses) {\n\t\t\t\t\tawait this.handleStatus(status);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error: unknown) {\n\t\t\tif (error instanceof Error) {\n\t\t\t\tthrow new Error(`Failed to send WhatsApp message: ${error.message}`);\n\t\t\t}\n\t\t\tthrow new Error(\"Failed to send WhatsApp message\");\n\t\t}\n\t}\n\n\tprivate async handleMessage(message: WhatsAppIncomingMessage): Promise<void> {\n\t\t// Implement message handling logic\n\t\t// This could emit events or trigger callbacks based on your framework's needs\n\t\tconsole.log(\"Received message:\", message);\n\t}\n\n\tprivate async handleStatus(status: WhatsAppStatusUpdate): Promise<void> {\n\t\t// Implement status update handling logic\n\t\t// This could emit events or trigger callbacks based on your framework's needs\n\t\tconsole.log(\"Received status update:\", status);\n\t}\n}\n",
18
+ "import type { IAgentRuntime } from \"@elizaos/core\";\nimport {\n\tcheckPairingAllowed,\n\tisInAllowlist,\n\ttype PairingCheckResult,\n} from \"@elizaos/core\";\n\n/**\n * Default account identifier used when no specific account is configured\n */\nexport const DEFAULT_ACCOUNT_ID = \"default\";\n\n/**\n * Token source indicator\n */\nexport type WhatsAppTokenSource = \"config\" | \"env\" | \"character\" | \"none\";\n\n/**\n * Group-specific runtime configuration (for account resolution)\n */\nexport interface WhatsAppGroupRuntimeConfig {\n\t/** If false, ignore messages from this group */\n\tenabled?: boolean;\n\t/** Allowlist for users in this group */\n\tallowFrom?: Array<string | number>;\n\t/** Require bot mention to respond */\n\trequireMention?: boolean;\n\t/** Custom system prompt for this group */\n\tsystemPrompt?: string;\n\t/** Skills enabled for this group */\n\tskills?: string[];\n}\n\n/**\n * Configuration for a single WhatsApp account (runtime resolution)\n */\nexport interface WhatsAppAccountRuntimeConfig {\n\t/** Optional display name for this account */\n\tname?: string;\n\t/** If false, do not start this WhatsApp account */\n\tenabled?: boolean;\n\t/** WhatsApp Cloud API access token */\n\taccessToken?: string;\n\t/** Phone number ID from WhatsApp Business */\n\tphoneNumberId?: string;\n\t/** Business account ID */\n\tbusinessAccountId?: string;\n\t/** Webhook verification token */\n\twebhookVerifyToken?: string;\n\t/** API version to use */\n\tapiVersion?: string;\n\t/** Allowlist for DM senders */\n\tallowFrom?: Array<string | number>;\n\t/** Allowlist for groups */\n\tgroupAllowFrom?: Array<string | number>;\n\t/** DM access policy */\n\tdmPolicy?: \"open\" | \"allowlist\" | \"pairing\" | \"disabled\";\n\t/** Group message access policy */\n\tgroupPolicy?: \"open\" | \"allowlist\" | \"disabled\";\n\t/** Max media size in MB */\n\tmediaMaxMb?: number;\n\t/** Text chunk limit for messages */\n\ttextChunkLimit?: number;\n\t/** Group-specific configurations */\n\tgroups?: Record<string, WhatsAppGroupRuntimeConfig>;\n}\n\n/**\n * Multi-account WhatsApp configuration structure\n */\nexport interface WhatsAppMultiAccountConfig {\n\t/** Default/base configuration applied to all accounts */\n\tenabled?: boolean;\n\taccessToken?: string;\n\tphoneNumberId?: string;\n\tbusinessAccountId?: string;\n\twebhookVerifyToken?: string;\n\tapiVersion?: string;\n\tdmPolicy?: \"open\" | \"allowlist\" | \"pairing\" | \"disabled\";\n\tgroupPolicy?: \"open\" | \"allowlist\" | \"disabled\";\n\tmediaMaxMb?: number;\n\ttextChunkLimit?: number;\n\t/** Per-account configuration overrides */\n\taccounts?: Record<string, WhatsAppAccountRuntimeConfig>;\n\t/** Group configurations at base level */\n\tgroups?: Record<string, WhatsAppGroupRuntimeConfig>;\n}\n\n/**\n * Token resolution result\n */\nexport interface WhatsAppTokenResolution {\n\ttoken: string;\n\tsource: WhatsAppTokenSource;\n}\n\n/**\n * Resolved WhatsApp account with all configuration merged\n */\nexport interface ResolvedWhatsAppAccount {\n\taccountId: string;\n\tenabled: boolean;\n\tname?: string;\n\taccessToken: string;\n\tphoneNumberId: string;\n\tbusinessAccountId?: string;\n\ttokenSource: WhatsAppTokenSource;\n\tconfigured: boolean;\n\tconfig: WhatsAppAccountRuntimeConfig;\n}\n\n/**\n * Normalizes an account ID, returning the default if not provided\n */\nexport function normalizeAccountId(accountId?: string | null): string {\n\tif (!accountId || typeof accountId !== \"string\") {\n\t\treturn DEFAULT_ACCOUNT_ID;\n\t}\n\tconst trimmed = accountId.trim().toLowerCase();\n\tif (!trimmed || trimmed === \"default\") {\n\t\treturn DEFAULT_ACCOUNT_ID;\n\t}\n\treturn trimmed;\n}\n\n/**\n * Gets the multi-account configuration from runtime settings\n */\nexport function getMultiAccountConfig(\n\truntime: IAgentRuntime,\n): WhatsAppMultiAccountConfig {\n\tconst characterWhatsApp = runtime.character?.settings?.whatsapp as\n\t\t| WhatsAppMultiAccountConfig\n\t\t| undefined;\n\n\treturn {\n\t\tenabled: characterWhatsApp?.enabled,\n\t\taccessToken: characterWhatsApp?.accessToken,\n\t\tphoneNumberId: characterWhatsApp?.phoneNumberId,\n\t\tbusinessAccountId: characterWhatsApp?.businessAccountId,\n\t\twebhookVerifyToken: characterWhatsApp?.webhookVerifyToken,\n\t\tapiVersion: characterWhatsApp?.apiVersion,\n\t\tdmPolicy: characterWhatsApp?.dmPolicy,\n\t\tgroupPolicy: characterWhatsApp?.groupPolicy,\n\t\tmediaMaxMb: characterWhatsApp?.mediaMaxMb,\n\t\ttextChunkLimit: characterWhatsApp?.textChunkLimit,\n\t\taccounts: characterWhatsApp?.accounts,\n\t\tgroups: characterWhatsApp?.groups,\n\t};\n}\n\n/**\n * Lists all configured account IDs\n */\nexport function listWhatsAppAccountIds(runtime: IAgentRuntime): string[] {\n\tconst config = getMultiAccountConfig(runtime);\n\tconst accounts = config.accounts;\n\tconst ids = new Set<string>();\n\n\t// Check if default account is configured\n\tconst envToken = runtime.getSetting(\"WHATSAPP_ACCESS_TOKEN\") as\n\t\t| string\n\t\t| undefined;\n\tconst envPhoneId = runtime.getSetting(\"WHATSAPP_PHONE_NUMBER_ID\") as\n\t\t| string\n\t\t| undefined;\n\n\tconst baseConfigured = Boolean(\n\t\tconfig.accessToken?.trim() && config.phoneNumberId?.trim(),\n\t);\n\tconst envConfigured = Boolean(envToken?.trim() && envPhoneId?.trim());\n\n\tif (baseConfigured || envConfigured) {\n\t\tids.add(DEFAULT_ACCOUNT_ID);\n\t}\n\n\t// Add named accounts\n\tif (accounts && typeof accounts === \"object\") {\n\t\tfor (const id of Object.keys(accounts)) {\n\t\t\tif (id) {\n\t\t\t\tids.add(normalizeAccountId(id));\n\t\t\t}\n\t\t}\n\t}\n\n\tconst result = Array.from(ids);\n\tif (result.length === 0) {\n\t\treturn [DEFAULT_ACCOUNT_ID];\n\t}\n\n\treturn result.slice().sort((a, b) => a.localeCompare(b));\n}\n\n/**\n * Resolves the default account ID to use\n */\nexport function resolveDefaultWhatsAppAccountId(\n\truntime: IAgentRuntime,\n): string {\n\tconst ids = listWhatsAppAccountIds(runtime);\n\tif (ids.includes(DEFAULT_ACCOUNT_ID)) {\n\t\treturn DEFAULT_ACCOUNT_ID;\n\t}\n\treturn ids[0] ?? DEFAULT_ACCOUNT_ID;\n}\n\n/**\n * Gets the account-specific configuration\n */\nfunction getAccountConfig(\n\truntime: IAgentRuntime,\n\taccountId: string,\n): WhatsAppAccountRuntimeConfig | undefined {\n\tconst config = getMultiAccountConfig(runtime);\n\tconst accounts = config.accounts;\n\n\tif (!accounts || typeof accounts !== \"object\") {\n\t\treturn undefined;\n\t}\n\n\t// Try direct match first\n\tconst direct = accounts[accountId];\n\tif (direct) {\n\t\treturn direct;\n\t}\n\n\t// Try normalized match\n\tconst normalized = normalizeAccountId(accountId);\n\tconst matchKey = Object.keys(accounts).find(\n\t\t(key) => normalizeAccountId(key) === normalized,\n\t);\n\treturn matchKey ? accounts[matchKey] : undefined;\n}\n\n/**\n * Resolves the access token for a WhatsApp account\n */\nexport function resolveWhatsAppToken(\n\truntime: IAgentRuntime,\n\taccountId: string,\n): WhatsAppTokenResolution {\n\tconst multiConfig = getMultiAccountConfig(runtime);\n\tconst accountConfig = getAccountConfig(runtime, accountId);\n\n\t// Check account-level config first\n\tif (accountConfig?.accessToken?.trim()) {\n\t\treturn { token: accountConfig.accessToken.trim(), source: \"config\" };\n\t}\n\n\t// For default account, check base config\n\tif (accountId === DEFAULT_ACCOUNT_ID) {\n\t\tif (multiConfig.accessToken?.trim()) {\n\t\t\treturn { token: multiConfig.accessToken.trim(), source: \"config\" };\n\t\t}\n\n\t\t// Check environment/runtime settings\n\t\tconst envToken = runtime.getSetting(\"WHATSAPP_ACCESS_TOKEN\") as\n\t\t\t| string\n\t\t\t| undefined;\n\t\tif (envToken?.trim()) {\n\t\t\treturn { token: envToken.trim(), source: \"env\" };\n\t\t}\n\t}\n\n\treturn { token: \"\", source: \"none\" };\n}\n\n/**\n * Merges base configuration with account-specific overrides\n */\n/**\n * Removes undefined values from an object to prevent them from overwriting during spread\n */\nfunction filterDefined<T extends object>(obj: T): Partial<T> {\n\treturn Object.fromEntries(\n\t\tObject.entries(obj).filter(([, v]) => v !== undefined),\n\t) as Partial<T>;\n}\n\nfunction mergeWhatsAppAccountConfig(\n\truntime: IAgentRuntime,\n\taccountId: string,\n): WhatsAppAccountRuntimeConfig {\n\tconst multiConfig = getMultiAccountConfig(runtime);\n\tconst { accounts: _ignored, ...baseConfig } = multiConfig;\n\tconst accountConfig = getAccountConfig(runtime, accountId) ?? {};\n\n\t// Get environment/runtime settings for the base config\n\tconst envToken = runtime.getSetting(\"WHATSAPP_ACCESS_TOKEN\") as\n\t\t| string\n\t\t| undefined;\n\tconst envPhoneId = runtime.getSetting(\"WHATSAPP_PHONE_NUMBER_ID\") as\n\t\t| string\n\t\t| undefined;\n\tconst envBusinessId = runtime.getSetting(\"WHATSAPP_BUSINESS_ACCOUNT_ID\") as\n\t\t| string\n\t\t| undefined;\n\tconst envWebhookToken = runtime.getSetting(\"WHATSAPP_WEBHOOK_VERIFY_TOKEN\") as\n\t\t| string\n\t\t| undefined;\n\tconst envDmPolicy = runtime.getSetting(\"WHATSAPP_DM_POLICY\") as\n\t\t| string\n\t\t| undefined;\n\tconst envGroupPolicy = runtime.getSetting(\"WHATSAPP_GROUP_POLICY\") as\n\t\t| string\n\t\t| undefined;\n\n\tconst envConfig: WhatsAppAccountRuntimeConfig = {\n\t\taccessToken: envToken || undefined,\n\t\tphoneNumberId: envPhoneId || undefined,\n\t\tbusinessAccountId: envBusinessId || undefined,\n\t\twebhookVerifyToken: envWebhookToken || undefined,\n\t\tdmPolicy: envDmPolicy as\n\t\t\t| WhatsAppAccountRuntimeConfig[\"dmPolicy\"]\n\t\t\t| undefined,\n\t\tgroupPolicy: envGroupPolicy as\n\t\t\t| WhatsAppAccountRuntimeConfig[\"groupPolicy\"]\n\t\t\t| undefined,\n\t};\n\n\t// Merge order: env defaults < base config < account config\n\t// Filter undefined values to prevent them from overwriting defined values\n\treturn {\n\t\t...filterDefined(envConfig),\n\t\t...filterDefined(baseConfig),\n\t\t...filterDefined(accountConfig),\n\t};\n}\n\n/**\n * Resolves a complete WhatsApp account configuration\n */\nexport function resolveWhatsAppAccount(\n\truntime: IAgentRuntime,\n\taccountId?: string | null,\n): ResolvedWhatsAppAccount {\n\tconst normalizedAccountId = normalizeAccountId(accountId);\n\tconst multiConfig = getMultiAccountConfig(runtime);\n\n\tconst baseEnabled = multiConfig.enabled !== false;\n\tconst merged = mergeWhatsAppAccountConfig(runtime, normalizedAccountId);\n\tconst accountEnabled = merged.enabled !== false;\n\tconst enabled = baseEnabled && accountEnabled;\n\n\tconst { token, source: tokenSource } = resolveWhatsAppToken(\n\t\truntime,\n\t\tnormalizedAccountId,\n\t);\n\tconst phoneNumberId = merged.phoneNumberId?.trim() || \"\";\n\n\t// Determine if this account is actually configured\n\tconst configured = Boolean(token && phoneNumberId);\n\n\treturn {\n\t\taccountId: normalizedAccountId,\n\t\tenabled,\n\t\tname: merged.name?.trim() || undefined,\n\t\taccessToken: token,\n\t\tphoneNumberId,\n\t\tbusinessAccountId: merged.businessAccountId?.trim() || undefined,\n\t\ttokenSource,\n\t\tconfigured,\n\t\tconfig: merged,\n\t};\n}\n\n/**\n * Lists all enabled WhatsApp accounts\n */\nexport function listEnabledWhatsAppAccounts(\n\truntime: IAgentRuntime,\n): ResolvedWhatsAppAccount[] {\n\treturn listWhatsAppAccountIds(runtime)\n\t\t.map((accountId) => resolveWhatsAppAccount(runtime, accountId))\n\t\t.filter((account) => account.enabled && account.configured);\n}\n\n/**\n * Checks if multi-account mode is enabled\n */\nexport function isMultiAccountEnabled(runtime: IAgentRuntime): boolean {\n\tconst accounts = listEnabledWhatsAppAccounts(runtime);\n\treturn accounts.length > 1;\n}\n\n/**\n * Resolves group configuration for a specific group\n */\nexport function resolveWhatsAppGroupConfig(\n\truntime: IAgentRuntime,\n\taccountId: string,\n\tgroupId: string,\n): WhatsAppGroupRuntimeConfig | undefined {\n\tconst multiConfig = getMultiAccountConfig(runtime);\n\tconst accountConfig = getAccountConfig(runtime, accountId);\n\n\t// Check account-level groups first\n\tconst accountGroup = accountConfig?.groups?.[groupId];\n\tif (accountGroup) {\n\t\treturn accountGroup;\n\t}\n\n\t// Fall back to base-level groups\n\treturn multiConfig.groups?.[groupId];\n}\n\n/**\n * Checks if a user is allowed based on policy and allowlist\n */\nexport function isWhatsAppUserAllowed(params: {\n\tidentifier: string;\n\taccountConfig: WhatsAppAccountRuntimeConfig;\n\tisGroup: boolean;\n\tgroupId?: string;\n\tgroupConfig?: WhatsAppGroupRuntimeConfig;\n}): boolean {\n\tconst { identifier, accountConfig, isGroup, groupConfig } = params;\n\n\tif (isGroup) {\n\t\tconst policy = accountConfig.groupPolicy ?? \"allowlist\";\n\t\tif (policy === \"disabled\") {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (policy === \"open\") {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check group-specific allowlist first\n\t\tif (groupConfig?.allowFrom?.length) {\n\t\t\treturn groupConfig.allowFrom.some(\n\t\t\t\t(allowed) => String(allowed) === identifier,\n\t\t\t);\n\t\t}\n\n\t\t// Check account-level group allowlist\n\t\tif (accountConfig.groupAllowFrom?.length) {\n\t\t\treturn accountConfig.groupAllowFrom.some(\n\t\t\t\t(allowed) => String(allowed) === identifier,\n\t\t\t);\n\t\t}\n\n\t\treturn policy !== \"allowlist\";\n\t}\n\n\t// DM handling\n\tconst policy = accountConfig.dmPolicy ?? \"pairing\";\n\tif (policy === \"disabled\") {\n\t\treturn false;\n\t}\n\n\tif (policy === \"open\") {\n\t\treturn true;\n\t}\n\n\tif (policy === \"pairing\") {\n\t\treturn true;\n\t}\n\n\t// Allowlist policy\n\tif (accountConfig.allowFrom?.length) {\n\t\treturn accountConfig.allowFrom.some(\n\t\t\t(allowed) => String(allowed) === identifier,\n\t\t);\n\t}\n\n\treturn false;\n}\n\n/**\n * Checks if mention is required in a group\n */\nexport function isWhatsAppMentionRequired(params: {\n\taccountConfig: WhatsAppAccountRuntimeConfig;\n\tgroupConfig?: WhatsAppGroupRuntimeConfig;\n}): boolean {\n\tconst { groupConfig } = params;\n\treturn groupConfig?.requireMention ?? false;\n}\n\n/**\n * Result of an async WhatsApp access check\n */\nexport interface WhatsAppAccessCheckResult {\n\t/** Whether the sender is allowed to proceed */\n\tallowed: boolean;\n\t/** If not allowed (pairing policy), the pairing code */\n\tpairingCode?: string;\n\t/** Whether a new pairing request was created */\n\tnewPairingRequest?: boolean;\n\t/** Human-readable message to send to the user when blocked */\n\treplyMessage?: string;\n}\n\n/**\n * Checks if a user is allowed based on policy and allowlist, with async pairing support.\n *\n * For non-pairing policies, this behaves identically to `isWhatsAppUserAllowed`.\n * For the \"pairing\" policy, this actually checks the PairingService allowlist\n * and creates pairing requests when needed.\n *\n * @example\n * ```typescript\n * const result = await checkWhatsAppUserAccess({\n * runtime,\n * identifier: message.from,\n * accountConfig,\n * isGroup: false,\n * metadata: { name: contact.name },\n * });\n *\n * if (!result.allowed) {\n * if (result.replyMessage) {\n * await sendMessage(result.replyMessage);\n * }\n * return; // Block message processing\n * }\n * ```\n */\nexport async function checkWhatsAppUserAccess(params: {\n\truntime: IAgentRuntime;\n\tidentifier: string;\n\taccountConfig: WhatsAppAccountRuntimeConfig;\n\tisGroup: boolean;\n\tgroupId?: string;\n\tgroupConfig?: WhatsAppGroupRuntimeConfig;\n\tmetadata?: Record<string, string>;\n}): Promise<WhatsAppAccessCheckResult> {\n\tconst { runtime, identifier, accountConfig, isGroup, groupConfig, metadata } =\n\t\tparams;\n\n\tif (isGroup) {\n\t\t// Group access - same logic as synchronous version\n\t\tconst policy = accountConfig.groupPolicy ?? \"allowlist\";\n\t\tif (policy === \"disabled\") {\n\t\t\treturn { allowed: false };\n\t\t}\n\n\t\tif (policy === \"open\") {\n\t\t\treturn { allowed: true };\n\t\t}\n\n\t\t// Check group-specific allowlist first\n\t\tif (groupConfig?.allowFrom?.length) {\n\t\t\tconst allowed = groupConfig.allowFrom.some(\n\t\t\t\t(a) => String(a) === identifier,\n\t\t\t);\n\t\t\treturn { allowed };\n\t\t}\n\n\t\t// Check account-level group allowlist\n\t\tif (accountConfig.groupAllowFrom?.length) {\n\t\t\tconst allowed = accountConfig.groupAllowFrom.some(\n\t\t\t\t(a) => String(a) === identifier,\n\t\t\t);\n\t\t\treturn { allowed };\n\t\t}\n\n\t\treturn { allowed: policy !== \"allowlist\" };\n\t}\n\n\t// DM handling\n\tconst policy = accountConfig.dmPolicy ?? \"pairing\";\n\tif (policy === \"disabled\") {\n\t\treturn { allowed: false };\n\t}\n\n\tif (policy === \"open\") {\n\t\treturn { allowed: true };\n\t}\n\n\tif (policy === \"pairing\") {\n\t\t// Use the PairingService for actual pairing workflow\n\t\tconst result: PairingCheckResult = await checkPairingAllowed(runtime, {\n\t\t\tchannel: \"whatsapp\",\n\t\t\tsenderId: identifier,\n\t\t\tmetadata,\n\t\t});\n\n\t\treturn {\n\t\t\tallowed: result.allowed,\n\t\t\tpairingCode: result.pairingCode,\n\t\t\tnewPairingRequest: result.newRequest,\n\t\t\treplyMessage: result.replyMessage,\n\t\t};\n\t}\n\n\t// Allowlist policy - check static allowlist first\n\tif (accountConfig.allowFrom?.length) {\n\t\tconst allowed = accountConfig.allowFrom.some(\n\t\t\t(a) => String(a) === identifier,\n\t\t);\n\t\tif (allowed) {\n\t\t\treturn { allowed: true };\n\t\t}\n\t}\n\n\t// Also check the dynamic pairing allowlist for the allowlist policy\n\tconst inDynamicAllowlist = await isInAllowlist(\n\t\truntime,\n\t\t\"whatsapp\",\n\t\tidentifier,\n\t);\n\treturn { allowed: inDynamicAllowlist };\n}\n",
19
+ "/**\n * WhatsApp text chunk limit\n */\nexport const WHATSAPP_TEXT_CHUNK_LIMIT = 4096;\n\n/**\n * Regex for WhatsApp user JID (e.g., \"41796666864:0@s.whatsapp.net\")\n */\nconst WHATSAPP_USER_JID_RE = /^(\\d+)(?::\\d+)?@s\\.whatsapp\\.net$/i;\n\n/**\n * Regex for WhatsApp LID (e.g., \"123@lid\")\n */\nconst WHATSAPP_LID_RE = /^(\\d+)@lid$/i;\n\n/**\n * Strips WhatsApp target prefixes from a value\n */\nfunction stripWhatsAppTargetPrefixes(value: string): string {\n\tlet candidate = value.trim();\n\tfor (;;) {\n\t\tconst before = candidate;\n\t\tcandidate = candidate.replace(/^whatsapp:/i, \"\").trim();\n\t\tif (candidate === before) {\n\t\t\treturn candidate;\n\t\t}\n\t}\n}\n\n/**\n * Normalizes a phone number to E.164 format\n */\nexport function normalizeE164(input: string): string {\n\tconst stripped = input.replace(/[\\s\\-().]+/g, \"\");\n\tconst digitsOnly = stripped.replace(/[^\\d+]/g, \"\");\n\n\tif (!digitsOnly) {\n\t\treturn \"\";\n\t}\n\n\t// If it starts with +, keep as-is (already E.164)\n\tif (digitsOnly.startsWith(\"+\")) {\n\t\treturn digitsOnly;\n\t}\n\n\t// If it starts with 00, replace with +\n\tif (digitsOnly.startsWith(\"00\")) {\n\t\treturn `+${digitsOnly.slice(2)}`;\n\t}\n\n\t// Assume it's a full number without the +\n\tif (digitsOnly.length >= 10) {\n\t\treturn `+${digitsOnly}`;\n\t}\n\n\t// Return as-is if too short\n\treturn digitsOnly;\n}\n\n/**\n * Checks if a value is a WhatsApp group JID (e.g., \"123456789-987654321@g.us\")\n */\nexport function isWhatsAppGroupJid(value: string): boolean {\n\tconst candidate = stripWhatsAppTargetPrefixes(value);\n\tconst lower = candidate.toLowerCase();\n\tif (!lower.endsWith(\"@g.us\")) {\n\t\treturn false;\n\t}\n\tconst localPart = candidate.slice(0, candidate.length - \"@g.us\".length);\n\tif (!localPart || localPart.includes(\"@\")) {\n\t\treturn false;\n\t}\n\treturn /^[0-9]+(-[0-9]+)*$/.test(localPart);\n}\n\n/**\n * Checks if a value looks like a WhatsApp user target\n * (e.g., \"41796666864:0@s.whatsapp.net\" or \"123@lid\")\n */\nexport function isWhatsAppUserTarget(value: string): boolean {\n\tconst candidate = stripWhatsAppTargetPrefixes(value);\n\treturn (\n\t\tWHATSAPP_USER_JID_RE.test(candidate) || WHATSAPP_LID_RE.test(candidate)\n\t);\n}\n\n/**\n * Extracts the phone number from a WhatsApp user JID\n * \"41796666864:0@s.whatsapp.net\" -> \"41796666864\"\n * \"123456@lid\" -> \"123456\"\n */\nfunction extractUserJidPhone(jid: string): string | null {\n\tconst userMatch = jid.match(WHATSAPP_USER_JID_RE);\n\tif (userMatch) {\n\t\treturn userMatch[1];\n\t}\n\tconst lidMatch = jid.match(WHATSAPP_LID_RE);\n\tif (lidMatch) {\n\t\treturn lidMatch[1];\n\t}\n\treturn null;\n}\n\n/**\n * Normalizes a WhatsApp target (phone number, user JID, or group JID)\n * Returns null if the target is invalid\n */\nexport function normalizeWhatsAppTarget(value: string): string | null {\n\tconst candidate = stripWhatsAppTargetPrefixes(value);\n\tif (!candidate) {\n\t\treturn null;\n\t}\n\n\t// Handle group JIDs\n\tif (isWhatsAppGroupJid(candidate)) {\n\t\tconst localPart = candidate.slice(0, candidate.length - \"@g.us\".length);\n\t\treturn `${localPart}@g.us`;\n\t}\n\n\t// Handle user JIDs (e.g., \"41796666864:0@s.whatsapp.net\")\n\tif (isWhatsAppUserTarget(candidate)) {\n\t\tconst phone = extractUserJidPhone(candidate);\n\t\tif (!phone) {\n\t\t\treturn null;\n\t\t}\n\t\tconst normalized = normalizeE164(phone);\n\t\treturn normalized.length > 1 ? normalized : null;\n\t}\n\n\t// If the caller passed a JID-ish string that we don't understand, fail fast.\n\t// Otherwise normalizeE164 would happily treat \"group:120@g.us\" as a phone number.\n\tif (candidate.includes(\"@\")) {\n\t\treturn null;\n\t}\n\n\t// Treat as a phone number\n\tconst normalized = normalizeE164(candidate);\n\treturn normalized.length > 1 ? normalized : null;\n}\n\n/**\n * Formats a WhatsApp ID for display\n */\nexport function formatWhatsAppId(id: string): string {\n\tif (isWhatsAppGroupJid(id)) {\n\t\treturn `group:${id}`;\n\t}\n\tconst normalized = normalizeWhatsAppTarget(id);\n\treturn normalized || id;\n}\n\n/**\n * Checks if a WhatsApp ID is a group\n */\nexport function isWhatsAppGroup(id: string): boolean {\n\treturn isWhatsAppGroupJid(id);\n}\n\n/**\n * Gets the chat type from a WhatsApp ID\n */\nexport function getWhatsAppChatType(id: string): \"group\" | \"user\" {\n\treturn isWhatsAppGroupJid(id) ? \"group\" : \"user\";\n}\n\n/**\n * Builds a WhatsApp JID from a phone number\n */\nexport function buildWhatsAppUserJid(phoneNumber: string): string {\n\tconst normalized = normalizeE164(phoneNumber);\n\tconst digits = normalized.replace(/^\\+/, \"\");\n\treturn `${digits}@s.whatsapp.net`;\n}\n\n/**\n * Options for text chunking\n */\nexport interface ChunkWhatsAppTextOpts {\n\tlimit?: number;\n}\n\n/**\n * Splits text at the last safe break point within the limit\n */\nfunction splitAtBreakPoint(\n\ttext: string,\n\tlimit: number,\n): { chunk: string; remainder: string } {\n\tif (text.length <= limit) {\n\t\treturn { chunk: text, remainder: \"\" };\n\t}\n\n\tconst searchArea = text.slice(0, limit);\n\n\t// Prefer double newlines (paragraph breaks)\n\tconst doubleNewline = searchArea.lastIndexOf(\"\\n\\n\");\n\tif (doubleNewline > limit * 0.5) {\n\t\treturn {\n\t\t\tchunk: text.slice(0, doubleNewline).trimEnd(),\n\t\t\tremainder: text.slice(doubleNewline + 2).trimStart(),\n\t\t};\n\t}\n\n\t// Try single newlines\n\tconst singleNewline = searchArea.lastIndexOf(\"\\n\");\n\tif (singleNewline > limit * 0.5) {\n\t\treturn {\n\t\t\tchunk: text.slice(0, singleNewline).trimEnd(),\n\t\t\tremainder: text.slice(singleNewline + 1).trimStart(),\n\t\t};\n\t}\n\n\t// Try sentence boundaries\n\tconst sentenceEnd = Math.max(\n\t\tsearchArea.lastIndexOf(\". \"),\n\t\tsearchArea.lastIndexOf(\"! \"),\n\t\tsearchArea.lastIndexOf(\"? \"),\n\t);\n\tif (sentenceEnd > limit * 0.5) {\n\t\treturn {\n\t\t\tchunk: text.slice(0, sentenceEnd + 1).trimEnd(),\n\t\t\tremainder: text.slice(sentenceEnd + 2).trimStart(),\n\t\t};\n\t}\n\n\t// Try word boundaries\n\tconst space = searchArea.lastIndexOf(\" \");\n\tif (space > limit * 0.5) {\n\t\treturn {\n\t\t\tchunk: text.slice(0, space).trimEnd(),\n\t\t\tremainder: text.slice(space + 1).trimStart(),\n\t\t};\n\t}\n\n\t// Hard break at limit\n\treturn {\n\t\tchunk: text.slice(0, limit),\n\t\tremainder: text.slice(limit),\n\t};\n}\n\n/**\n * Chunks text for WhatsApp messages\n */\nexport function chunkWhatsAppText(\n\ttext: string,\n\topts: ChunkWhatsAppTextOpts = {},\n): string[] {\n\tconst limit = opts.limit ?? WHATSAPP_TEXT_CHUNK_LIMIT;\n\n\tif (!text?.trim()) {\n\t\treturn [];\n\t}\n\n\tconst normalizedText = text.trim();\n\tif (normalizedText.length <= limit) {\n\t\treturn [normalizedText];\n\t}\n\n\tconst chunks: string[] = [];\n\tlet remaining = normalizedText;\n\n\twhile (remaining.length > 0) {\n\t\tconst { chunk, remainder } = splitAtBreakPoint(remaining, limit);\n\t\tif (chunk) {\n\t\t\tchunks.push(chunk);\n\t\t}\n\t\tremaining = remainder;\n\t}\n\n\treturn chunks.filter((c) => c.length > 0);\n}\n\n/**\n * Truncates text to a maximum length with ellipsis\n */\nexport function truncateText(text: string, maxLength: number): string {\n\tif (text.length <= maxLength) {\n\t\treturn text;\n\t}\n\tif (maxLength <= 3) {\n\t\treturn \"...\".slice(0, maxLength);\n\t}\n\treturn `${text.slice(0, maxLength - 3)}...`;\n}\n\n/**\n * Resolves the system location string for logging\n */\nexport function resolveWhatsAppSystemLocation(params: {\n\tchatType: \"group\" | \"user\";\n\tchatId: string;\n\tchatName?: string;\n}): string {\n\tconst { chatType, chatId, chatName } = params;\n\tconst name = chatName || chatId.slice(0, 8);\n\treturn `WhatsApp ${chatType}:${name}`;\n}\n\n/**\n * Validates a WhatsApp phone number\n */\nexport function isValidWhatsAppNumber(value: string): boolean {\n\tconst normalized = normalizeWhatsAppTarget(value);\n\tif (!normalized) {\n\t\treturn false;\n\t}\n\t// Must be E.164 format with at least 10 digits\n\tif (!normalized.startsWith(\"+\")) {\n\t\treturn false;\n\t}\n\tconst digits = normalized.replace(/^\\+/, \"\");\n\treturn /^\\d{10,15}$/.test(digits);\n}\n\n/**\n * Formats a phone number for WhatsApp display\n */\nexport function formatWhatsAppPhoneNumber(phoneNumber: string): string {\n\tconst normalized = normalizeE164(phoneNumber);\n\tif (!normalized) {\n\t\treturn phoneNumber;\n\t}\n\t// Format as +XX XXX XXX XXXX for display\n\tconst digits = normalized.replace(/^\\+/, \"\");\n\tif (digits.length <= 10) {\n\t\treturn normalized;\n\t}\n\t// Simple formatting: country code + rest\n\tconst countryCode = digits.slice(0, digits.length - 10);\n\tconst rest = digits.slice(-10);\n\treturn `+${countryCode} ${rest.slice(0, 3)} ${rest.slice(3, 6)} ${rest.slice(6)}`;\n}\n",
20
+ "export type WhatsAppConfig = CloudAPIConfig | BaileysConfig;\n\nexport interface CloudAPIConfig {\n\tauthMethod?: \"cloudapi\";\n\taccessToken: string;\n\tphoneNumberId: string;\n\twebhookVerifyToken?: string;\n\tbusinessAccountId?: string;\n\tapiVersion?: string;\n}\n\nexport interface BaileysConfig {\n\tauthMethod?: \"baileys\";\n\tauthDir: string;\n\tprintQRInTerminal?: boolean;\n\tsessionPath?: string;\n}\n\n/**\n * Message types supported by WhatsApp Cloud API.\n */\nexport type WhatsAppMessageType =\n\t| \"text\"\n\t| \"template\"\n\t| \"image\"\n\t| \"audio\"\n\t| \"video\"\n\t| \"document\"\n\t| \"sticker\"\n\t| \"location\"\n\t| \"contacts\"\n\t| \"interactive\"\n\t| \"reaction\";\n\nexport interface WhatsAppMessage {\n\ttype: WhatsAppMessageType;\n\tto: string;\n\tcontent:\n\t\t| string\n\t\t| WhatsAppTemplate\n\t\t| WhatsAppMediaMessage\n\t\t| WhatsAppInteractiveMessage\n\t\t| WhatsAppReactionMessage\n\t\t| WhatsAppLocationMessage;\n\treplyToMessageId?: string;\n}\n\nexport interface WhatsAppTemplate {\n\tname: string;\n\tlanguage: {\n\t\tcode: string;\n\t};\n\tcomponents?: Array<{\n\t\ttype: string;\n\t\tparameters: Array<{\n\t\t\ttype: string;\n\t\t\ttext?: string;\n\t\t\timage?: { link: string };\n\t\t\tdocument?: { link: string; filename?: string };\n\t\t\tvideo?: { link: string };\n\t\t}>;\n\t}>;\n}\n\n/**\n * Media message content.\n */\nexport interface WhatsAppMediaMessage {\n\tlink?: string;\n\tid?: string;\n\tcaption?: string;\n\tfilename?: string;\n\tmimeType?: string;\n}\n\n/**\n * Reaction message content.\n */\nexport interface WhatsAppReactionMessage {\n\tmessageId: string;\n\temoji: string;\n}\n\n/**\n * Location message content.\n */\nexport interface WhatsAppLocationMessage {\n\tlatitude: number;\n\tlongitude: number;\n\tname?: string;\n\taddress?: string;\n}\n\n/**\n * Interactive message types.\n */\nexport type InteractiveMessageType =\n\t| \"button\"\n\t| \"list\"\n\t| \"product\"\n\t| \"product_list\"\n\t| \"flow\";\n\n/**\n * Interactive message content.\n */\nexport interface WhatsAppInteractiveMessage {\n\ttype: InteractiveMessageType;\n\theader?: {\n\t\ttype: \"text\" | \"image\" | \"video\" | \"document\";\n\t\ttext?: string;\n\t\timage?: { link: string };\n\t\tvideo?: { link: string };\n\t\tdocument?: { link: string; filename?: string };\n\t};\n\tbody: {\n\t\ttext: string;\n\t};\n\tfooter?: {\n\t\ttext: string;\n\t};\n\taction: WhatsAppInteractiveAction;\n}\n\n/**\n * Interactive action based on message type.\n */\nexport type WhatsAppInteractiveAction =\n\t| WhatsAppButtonAction\n\t| WhatsAppListAction\n\t| WhatsAppFlowAction;\n\n/**\n * Button action for interactive messages.\n */\nexport interface WhatsAppButtonAction {\n\tbuttons: Array<{\n\t\ttype: \"reply\";\n\t\treply: {\n\t\t\tid: string;\n\t\t\ttitle: string;\n\t\t};\n\t}>;\n}\n\n/**\n * List action for interactive messages.\n */\nexport interface WhatsAppListAction {\n\tbutton: string;\n\tsections: Array<{\n\t\ttitle?: string;\n\t\trows: Array<{\n\t\t\tid: string;\n\t\t\ttitle: string;\n\t\t\tdescription?: string;\n\t\t}>;\n\t}>;\n}\n\n/**\n * Flow action for interactive messages.\n */\nexport interface WhatsAppFlowAction {\n\tname: \"flow\";\n\tparameters: {\n\t\tflow_message_version: string;\n\t\tflow_token: string;\n\t\tflow_id: string;\n\t\tflow_cta: string;\n\t\tflow_action: \"navigate\" | \"data_exchange\";\n\t\tflow_action_payload?: {\n\t\t\tscreen: string;\n\t\t\tdata?: Record<string, unknown>;\n\t\t};\n\t};\n}\n\nexport interface WhatsAppIncomingMessage {\n\tfrom: string;\n\tid: string;\n\ttimestamp: string;\n\ttext?: {\n\t\tbody: string;\n\t};\n\timage?: {\n\t\tcaption?: string;\n\t\tmime_type: string;\n\t\tsha256: string;\n\t\tid: string;\n\t};\n\tvideo?: {\n\t\tcaption?: string;\n\t\tmime_type: string;\n\t\tsha256: string;\n\t\tid: string;\n\t};\n\taudio?: {\n\t\tmime_type: string;\n\t\tsha256: string;\n\t\tid: string;\n\t\tvoice?: boolean;\n\t};\n\tdocument?: {\n\t\tcaption?: string;\n\t\tfilename: string;\n\t\tmime_type: string;\n\t\tsha256: string;\n\t\tid: string;\n\t};\n\tsticker?: {\n\t\tmime_type: string;\n\t\tsha256: string;\n\t\tid: string;\n\t\tanimated?: boolean;\n\t};\n\tlocation?: {\n\t\tlatitude: number;\n\t\tlongitude: number;\n\t\tname?: string;\n\t\taddress?: string;\n\t};\n\tcontacts?: Array<{\n\t\tname: {\n\t\t\tformatted_name: string;\n\t\t\tfirst_name?: string;\n\t\t\tlast_name?: string;\n\t\t};\n\t\tphones?: Array<{\n\t\t\tphone: string;\n\t\t\ttype: string;\n\t\t}>;\n\t}>;\n\tinteractive?: {\n\t\ttype: \"button_reply\" | \"list_reply\" | \"nfm_reply\";\n\t\tbutton_reply?: {\n\t\t\tid: string;\n\t\t\ttitle: string;\n\t\t};\n\t\tlist_reply?: {\n\t\t\tid: string;\n\t\t\ttitle: string;\n\t\t\tdescription?: string;\n\t\t};\n\t\tnfm_reply?: {\n\t\t\tresponse_json: string;\n\t\t\tbody: string;\n\t\t\tname: string;\n\t\t};\n\t};\n\treaction?: {\n\t\tmessage_id: string;\n\t\temoji: string;\n\t};\n\tcontext?: {\n\t\tfrom: string;\n\t\tid: string;\n\t\treferred_product?: {\n\t\t\tcatalog_id: string;\n\t\t\tproduct_retailer_id: string;\n\t\t};\n\t};\n\ttype: string;\n}\n\nexport interface WhatsAppStatusUpdate {\n\tid: string;\n\tstatus: \"sent\" | \"delivered\" | \"read\" | \"failed\";\n\ttimestamp: string;\n\trecipient_id: string;\n\tconversation?: {\n\t\tid: string;\n\t\torigin?: {\n\t\t\ttype: string;\n\t\t};\n\t\texpiration_timestamp?: string;\n\t};\n\tpricing?: {\n\t\tbillable: boolean;\n\t\tpricing_model: string;\n\t\tcategory: string;\n\t};\n\terrors?: Array<{\n\t\tcode: number;\n\t\ttitle: string;\n\t\tmessage?: string;\n\t\terror_data?: {\n\t\t\tdetails: string;\n\t\t};\n\t}>;\n}\n\nexport interface WhatsAppWebhookEvent {\n\tobject: string;\n\tentry: Array<{\n\t\tid: string;\n\t\tchanges: Array<{\n\t\t\tvalue: {\n\t\t\t\tmessaging_product: string;\n\t\t\t\tmetadata: {\n\t\t\t\t\tdisplay_phone_number: string;\n\t\t\t\t\tphone_number_id: string;\n\t\t\t\t};\n\t\t\t\tstatuses?: WhatsAppStatusUpdate[];\n\t\t\t\tmessages?: WhatsAppIncomingMessage[];\n\t\t\t\tcontacts?: Array<{\n\t\t\t\t\tprofile: {\n\t\t\t\t\t\tname: string;\n\t\t\t\t\t};\n\t\t\t\t\twa_id: string;\n\t\t\t\t}>;\n\t\t\t\terrors?: Array<{\n\t\t\t\t\tcode: number;\n\t\t\t\t\ttitle: string;\n\t\t\t\t\tmessage?: string;\n\t\t\t\t\terror_data?: {\n\t\t\t\t\t\tdetails: string;\n\t\t\t\t\t};\n\t\t\t\t}>;\n\t\t\t};\n\t\t\tfield: string;\n\t\t}>;\n\t}>;\n}\n\nexport interface WhatsAppMessageResponse {\n\tmessaging_product: string;\n\tcontacts: Array<{\n\t\tinput: string;\n\t\twa_id: string;\n\t}>;\n\tmessages: Array<{\n\t\tid: string;\n\t\tmessage_status?: string;\n\t}>;\n}\n\nexport interface QRCodeData {\n\tterminal: string;\n\tdataURL: string;\n\traw: string;\n}\n\nexport type ConnectionStatus = \"connecting\" | \"open\" | \"close\";\n\nexport interface UnifiedMessage {\n\tid: string;\n\tfrom: string;\n\ttimestamp: number;\n\ttype: \"text\" | \"image\" | \"audio\" | \"video\" | \"document\";\n\tcontent: string;\n}\n\n/**\n * Send reaction parameters.\n */\nexport interface SendReactionParams {\n\tto: string;\n\tmessageId: string;\n\temoji: string;\n}\n\n/**\n * Send reaction result.\n */\nexport interface SendReactionResult {\n\tsuccess: boolean;\n\tmessageId?: string;\n\terror?: string;\n}\n\n/**\n * WhatsApp event types.\n */\nexport enum WhatsAppEventType {\n\tMESSAGE_RECEIVED = \"WHATSAPP_MESSAGE_RECEIVED\",\n\tMESSAGE_SENT = \"WHATSAPP_MESSAGE_SENT\",\n\tMESSAGE_DELIVERED = \"WHATSAPP_MESSAGE_DELIVERED\",\n\tMESSAGE_READ = \"WHATSAPP_MESSAGE_READ\",\n\tMESSAGE_FAILED = \"WHATSAPP_MESSAGE_FAILED\",\n\tREACTION_RECEIVED = \"WHATSAPP_REACTION_RECEIVED\",\n\tREACTION_SENT = \"WHATSAPP_REACTION_SENT\",\n\tINTERACTIVE_REPLY = \"WHATSAPP_INTERACTIVE_REPLY\",\n\tWEBHOOK_VERIFIED = \"WHATSAPP_WEBHOOK_VERIFIED\",\n}\n\n/**\n * Common WhatsApp reaction emojis.\n */\nexport const WHATSAPP_REACTIONS = {\n\tTHUMBS_UP: \"👍\",\n\tTHUMBS_DOWN: \"👎\",\n\tHEART: \"❤️\",\n\tLAUGHING: \"😂\",\n\tSURPRISED: \"😮\",\n\tSAD: \"😢\",\n\tPRAYING: \"🙏\",\n\tCLAPPING: \"👏\",\n\tFIRE: \"🔥\",\n\tCELEBRATION: \"🎉\",\n} as const;\n\nexport type WhatsAppReactionEmoji =\n\t(typeof WHATSAPP_REACTIONS)[keyof typeof WHATSAPP_REACTIONS];\n"
21
21
  ],
22
- "mappings": "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",
23
- "debugId": "3ABF74EE0B1ACBEC64756E2164756E21",
22
+ "mappings": "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",
23
+ "debugId": "2FB406236C995FEF64756E2164756E21",
24
24
  "names": []
25
25
  }
package/package.json CHANGED
@@ -1,131 +1,133 @@
1
1
  {
2
- "name": "@elizaos/plugin-whatsapp",
3
- "description": "WhatsApp plugin for ElizaOS (Cloud API + Baileys QR auth)",
4
- "version": "2.0.0-alpha.7",
5
- "type": "module",
6
- "main": "dist/index.js",
7
- "module": "dist/index.js",
8
- "types": "dist/index.d.ts",
9
- "packageType": "plugin",
10
- "platform": "node",
11
- "license": "MIT",
12
- "keywords": [
13
- "plugin",
14
- "elizaos",
15
- "whatsapp"
16
- ],
17
- "repository": {
18
- "type": "git",
19
- "url": "https://github.com/elizaos/eliza"
20
- },
21
- "exports": {
22
- "./package.json": "./package.json",
23
- ".": {
24
- "import": {
25
- "types": "./dist/index.d.ts",
26
- "default": "./dist/index.js"
27
- }
28
- }
29
- },
30
- "files": [
31
- "dist",
32
- "README.md",
33
- "package.json"
34
- ],
35
- "dependencies": {
36
- "@hapi/boom": "^10.0.1",
37
- "@whiskeysockets/baileys": "^7.0.0-rc.9",
38
- "axios": "1.7.8",
39
- "pino": "^9.6.0",
40
- "qrcode": "^1.5.4",
41
- "qrcode-terminal": "^0.12.0"
42
- },
43
- "peerDependencies": {
44
- "@elizaos/core": "2.0.0-alpha.3"
45
- },
46
- "devDependencies": {
47
- "@biomejs/biome": "^2.3.11",
48
- "@types/node": "^25.0.3",
49
- "typescript": "^5.9.3",
50
- "vitest": "^3.2.4"
51
- },
52
- "scripts": {
53
- "dev": "bun --hot build.ts",
54
- "test": "vitest run || echo 'TypeScript tests skipped - no tests found'",
55
- "lint": "echo \"Lint skipped for release\"",
56
- "typecheck": "echo \"Typecheck skipped for release\"",
57
- "clean": "rm -rf dist .turbo",
58
- "lint:check": "bun run lint",
59
- "build": "bun run build.ts",
60
- "build:ts": "bun run build.ts",
61
- "format": "bunx @biomejs/biome format --write .",
62
- "format:check": "bunx @biomejs/biome format ."
63
- },
64
- "publishConfig": {
65
- "access": "public"
66
- },
67
- "agentConfig": {
68
- "pluginParameters": {
69
- "WHATSAPP_ACCESS_TOKEN": {
70
- "type": "string",
71
- "description": "Access token for WhatsApp Cloud API (required for cloudapi auth)",
72
- "required": false,
73
- "sensitive": true
74
- },
75
- "WHATSAPP_PHONE_NUMBER_ID": {
76
- "type": "string",
77
- "description": "Phone number ID for WhatsApp Cloud API (required for cloudapi auth)",
78
- "required": false,
79
- "sensitive": false
80
- },
81
- "WHATSAPP_AUTH_METHOD": {
82
- "type": "string",
83
- "description": "Authentication method: cloudapi or baileys",
84
- "required": false,
85
- "sensitive": false
86
- },
87
- "WHATSAPP_AUTH_DIR": {
88
- "type": "string",
89
- "description": "Directory used to persist Baileys session files (required for baileys auth)",
90
- "required": false,
91
- "sensitive": false
92
- },
93
- "WHATSAPP_PRINT_QR": {
94
- "type": "boolean",
95
- "description": "Print QR code in terminal when using Baileys auth",
96
- "required": false,
97
- "sensitive": false
98
- },
99
- "WHATSAPP_WEBHOOK_VERIFY_TOKEN": {
100
- "type": "string",
101
- "description": "Webhook verification token",
102
- "required": false,
103
- "sensitive": true
104
- },
105
- "WHATSAPP_BUSINESS_ACCOUNT_ID": {
106
- "type": "string",
107
- "description": "Business account ID",
108
- "required": false,
109
- "sensitive": false
110
- },
111
- "WHATSAPP_API_VERSION": {
112
- "type": "string",
113
- "description": "API version string",
114
- "required": false,
115
- "sensitive": false
116
- },
117
- "WHATSAPP_DM_POLICY": {
118
- "type": "string",
119
- "description": "DM policy (e.g. allow, deny, allowlist)",
120
- "required": false,
121
- "sensitive": false
122
- },
123
- "WHATSAPP_GROUP_POLICY": {
124
- "type": "string",
125
- "description": "Group message policy",
126
- "required": false,
127
- "sensitive": false
128
- }
129
- }
130
- }
2
+ "name": "@elizaos/plugin-whatsapp",
3
+ "description": "WhatsApp plugin for ElizaOS (Cloud API + Baileys QR auth)",
4
+ "version": "2.0.0-alpha.9",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "packageType": "plugin",
10
+ "platform": "node",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "plugin",
14
+ "elizaos",
15
+ "whatsapp"
16
+ ],
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/elizaos/eliza"
20
+ },
21
+ "exports": {
22
+ "./package.json": "./package.json",
23
+ ".": {
24
+ "import": {
25
+ "types": "./dist/index.d.ts",
26
+ "default": "./dist/index.js"
27
+ }
28
+ }
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "README.md",
33
+ "package.json"
34
+ ],
35
+ "dependencies": {
36
+ "@hapi/boom": "^10.0.1",
37
+ "@whiskeysockets/baileys": "^7.0.0-rc.9",
38
+ "axios": "1.7.8",
39
+ "pino": "^9.6.0",
40
+ "qrcode": "^1.5.4",
41
+ "qrcode-terminal": "^0.12.0"
42
+ },
43
+ "peerDependencies": {
44
+ "@elizaos/core": "2.0.0-alpha.3"
45
+ },
46
+ "devDependencies": {
47
+ "@biomejs/biome": "^2.3.11",
48
+ "@types/node": "^25.0.3",
49
+ "@types/qrcode": "^1.5.6",
50
+ "@types/qrcode-terminal": "^0.12.2",
51
+ "typescript": "^5.9.3",
52
+ "vitest": "^3.2.4"
53
+ },
54
+ "scripts": {
55
+ "dev": "bun --hot build.ts",
56
+ "test": "vitest run --passWithNoTests",
57
+ "lint": "echo \"Lint skipped for release\"",
58
+ "typecheck": "echo \"Typecheck skipped for release\"",
59
+ "clean": "rm -rf dist .turbo",
60
+ "lint:check": "bun run lint",
61
+ "build": "bun run build.ts",
62
+ "build:ts": "bun run build.ts",
63
+ "format": "bunx @biomejs/biome format --write .",
64
+ "format:check": "bunx @biomejs/biome format ."
65
+ },
66
+ "publishConfig": {
67
+ "access": "public"
68
+ },
69
+ "agentConfig": {
70
+ "pluginParameters": {
71
+ "WHATSAPP_ACCESS_TOKEN": {
72
+ "type": "string",
73
+ "description": "Access token for WhatsApp Cloud API (required for cloudapi auth)",
74
+ "required": false,
75
+ "sensitive": true
76
+ },
77
+ "WHATSAPP_PHONE_NUMBER_ID": {
78
+ "type": "string",
79
+ "description": "Phone number ID for WhatsApp Cloud API (required for cloudapi auth)",
80
+ "required": false,
81
+ "sensitive": false
82
+ },
83
+ "WHATSAPP_AUTH_METHOD": {
84
+ "type": "string",
85
+ "description": "Authentication method: cloudapi or baileys",
86
+ "required": false,
87
+ "sensitive": false
88
+ },
89
+ "WHATSAPP_AUTH_DIR": {
90
+ "type": "string",
91
+ "description": "Directory used to persist Baileys session files (required for baileys auth)",
92
+ "required": false,
93
+ "sensitive": false
94
+ },
95
+ "WHATSAPP_PRINT_QR": {
96
+ "type": "boolean",
97
+ "description": "Print QR code in terminal when using Baileys auth",
98
+ "required": false,
99
+ "sensitive": false
100
+ },
101
+ "WHATSAPP_WEBHOOK_VERIFY_TOKEN": {
102
+ "type": "string",
103
+ "description": "Webhook verification token",
104
+ "required": false,
105
+ "sensitive": true
106
+ },
107
+ "WHATSAPP_BUSINESS_ACCOUNT_ID": {
108
+ "type": "string",
109
+ "description": "Business account ID",
110
+ "required": false,
111
+ "sensitive": false
112
+ },
113
+ "WHATSAPP_API_VERSION": {
114
+ "type": "string",
115
+ "description": "API version string",
116
+ "required": false,
117
+ "sensitive": false
118
+ },
119
+ "WHATSAPP_DM_POLICY": {
120
+ "type": "string",
121
+ "description": "DM policy (e.g. allow, deny, allowlist)",
122
+ "required": false,
123
+ "sensitive": false
124
+ },
125
+ "WHATSAPP_GROUP_POLICY": {
126
+ "type": "string",
127
+ "description": "Group message policy",
128
+ "required": false,
129
+ "sensitive": false
130
+ }
131
+ }
132
+ }
131
133
  }