@elizaos/plugin-whatsapp 2.0.0-alpha.8 → 2.0.0-beta.1

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 (54) hide show
  1. package/README.md +283 -0
  2. package/auto-enable.ts +21 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/accounts.d.ts +205 -0
  5. package/dist/accounts.d.ts.map +1 -0
  6. package/dist/actions/index.d.ts +1 -0
  7. package/dist/actions/index.d.ts.map +1 -0
  8. package/dist/api/whatsapp-routes.d.ts +53 -0
  9. package/dist/api/whatsapp-routes.d.ts.map +1 -0
  10. package/dist/baileys/auth.d.ts +10 -0
  11. package/dist/baileys/auth.d.ts.map +1 -0
  12. package/dist/baileys/connection.d.ts +19 -0
  13. package/dist/baileys/connection.d.ts.map +1 -0
  14. package/dist/baileys/message-adapter.d.ts +14 -0
  15. package/dist/baileys/message-adapter.d.ts.map +1 -0
  16. package/dist/baileys/qr-code.d.ts +6 -0
  17. package/dist/baileys/qr-code.d.ts.map +1 -0
  18. package/dist/client.d.ts +99 -0
  19. package/dist/client.d.ts.map +1 -0
  20. package/dist/clients/baileys-client.d.ts +18 -0
  21. package/dist/clients/baileys-client.d.ts.map +1 -0
  22. package/dist/clients/factory.d.ts +6 -0
  23. package/dist/clients/factory.d.ts.map +1 -0
  24. package/dist/clients/interface.d.ts +10 -0
  25. package/dist/clients/interface.d.ts.map +1 -0
  26. package/dist/config.d.ts +135 -0
  27. package/dist/config.d.ts.map +1 -0
  28. package/dist/connector-account-provider.d.ts +19 -0
  29. package/dist/connector-account-provider.d.ts.map +1 -0
  30. package/dist/index.d.ts +14 -2
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +2353 -823
  33. package/dist/index.js.map +20 -18
  34. package/dist/normalize.d.ts +69 -0
  35. package/dist/normalize.d.ts.map +1 -0
  36. package/dist/pairing-service.d.ts +41 -0
  37. package/dist/pairing-service.d.ts.map +1 -0
  38. package/dist/runtime-service.d.ts +116 -0
  39. package/dist/runtime-service.d.ts.map +1 -0
  40. package/dist/services/whatsapp-pairing.d.ts +41 -0
  41. package/dist/services/whatsapp-pairing.d.ts.map +1 -0
  42. package/dist/setup-routes.d.ts +26 -0
  43. package/dist/setup-routes.d.ts.map +1 -0
  44. package/dist/types.d.ts +370 -0
  45. package/dist/types.d.ts.map +1 -0
  46. package/dist/utils/config-detector.d.ts +3 -0
  47. package/dist/utils/config-detector.d.ts.map +1 -0
  48. package/dist/utils/index.d.ts +3 -0
  49. package/dist/utils/index.d.ts.map +1 -0
  50. package/dist/utils/validators.d.ts +10 -0
  51. package/dist/utils/validators.d.ts.map +1 -0
  52. package/dist/workflow-credential-provider.d.ts +21 -0
  53. package/dist/workflow-credential-provider.d.ts.map +1 -0
  54. package/package.json +24 -16
@@ -0,0 +1,69 @@
1
+ /**
2
+ * WhatsApp text chunk limit
3
+ */
4
+ export declare const WHATSAPP_TEXT_CHUNK_LIMIT = 4096;
5
+ /**
6
+ * Normalizes a phone number to E.164 format
7
+ */
8
+ export declare function normalizeE164(input: string): string;
9
+ /**
10
+ * Checks if a value is a WhatsApp group JID (e.g., "123456789-987654321@g.us")
11
+ */
12
+ export declare function isWhatsAppGroupJid(value: string): boolean;
13
+ /**
14
+ * Checks if a value looks like a WhatsApp user target
15
+ * (e.g., "41796666864:0@s.whatsapp.net" or "123@lid")
16
+ */
17
+ export declare function isWhatsAppUserTarget(value: string): boolean;
18
+ /**
19
+ * Normalizes a WhatsApp target (phone number, user JID, or group JID)
20
+ * Returns null if the target is invalid
21
+ */
22
+ export declare function normalizeWhatsAppTarget(value: string): string | null;
23
+ /**
24
+ * Formats a WhatsApp ID for display
25
+ */
26
+ export declare function formatWhatsAppId(id: string): string;
27
+ /**
28
+ * Checks if a WhatsApp ID is a group
29
+ */
30
+ export declare function isWhatsAppGroup(id: string): boolean;
31
+ /**
32
+ * Gets the chat type from a WhatsApp ID
33
+ */
34
+ export declare function getWhatsAppChatType(id: string): "group" | "user";
35
+ /**
36
+ * Builds a WhatsApp JID from a phone number
37
+ */
38
+ export declare function buildWhatsAppUserJid(phoneNumber: string): string;
39
+ /**
40
+ * Options for text chunking
41
+ */
42
+ export interface ChunkWhatsAppTextOpts {
43
+ limit?: number;
44
+ }
45
+ /**
46
+ * Chunks text for WhatsApp messages
47
+ */
48
+ export declare function chunkWhatsAppText(text: string, opts?: ChunkWhatsAppTextOpts): string[];
49
+ /**
50
+ * Truncates text to a maximum length with ellipsis
51
+ */
52
+ export declare function truncateText(text: string, maxLength: number): string;
53
+ /**
54
+ * Resolves the system location string for logging
55
+ */
56
+ export declare function resolveWhatsAppSystemLocation(params: {
57
+ chatType: "group" | "user";
58
+ chatId: string;
59
+ chatName?: string;
60
+ }): string;
61
+ /**
62
+ * Validates a WhatsApp phone number
63
+ */
64
+ export declare function isValidWhatsAppNumber(value: string): boolean;
65
+ /**
66
+ * Formats a phone number for WhatsApp display
67
+ */
68
+ export declare function formatWhatsAppPhoneNumber(phoneNumber: string): string;
69
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,yBAAyB,OAAO,CAAC;AA0B9C;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAyBnD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAWzD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG3D;AAmBD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA+BpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAMnD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAEhE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAIhE;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA2DD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,MAAM,EAAE,CAwB1F;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAQpE;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE;IACpD,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,MAAM,CAIT;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAW5D;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAcrE"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * WhatsApp pairing service — manages Baileys sessions for QR code authentication.
3
+ *
4
+ * This service is separate from the main WhatsApp plugin because the plugin
5
+ * initializes during runtime startup (too late for interactive QR flow).
6
+ * Once pairing succeeds, the auth state is persisted to disk so the plugin
7
+ * can reconnect automatically on subsequent startups.
8
+ */
9
+ /** Validate accountId to prevent path traversal. Only allows alphanumeric, dash, underscore. */
10
+ export declare function sanitizeAccountId(raw: string): string;
11
+ export type WhatsAppPairingStatus = "idle" | "initializing" | "waiting_for_qr" | "connected" | "disconnected" | "timeout" | "error";
12
+ export interface WhatsAppPairingEvent {
13
+ type: "whatsapp-qr" | "whatsapp-status";
14
+ accountId: string;
15
+ qrDataUrl?: string;
16
+ expiresInMs?: number;
17
+ status?: WhatsAppPairingStatus;
18
+ phoneNumber?: string;
19
+ error?: string;
20
+ }
21
+ export interface WhatsAppPairingOptions {
22
+ authDir: string;
23
+ accountId: string;
24
+ onEvent: (event: WhatsAppPairingEvent) => void;
25
+ }
26
+ export declare class WhatsAppPairingSession {
27
+ private socket;
28
+ private status;
29
+ private options;
30
+ private qrAttempts;
31
+ private readonly MAX_QR_ATTEMPTS;
32
+ private restartTimer;
33
+ constructor(options: WhatsAppPairingOptions);
34
+ start(): Promise<void>;
35
+ stop(): void;
36
+ getStatus(): WhatsAppPairingStatus;
37
+ private setStatus;
38
+ }
39
+ export declare function whatsappAuthExists(workspaceDir: string, accountId?: string): boolean;
40
+ export declare function whatsappLogout(workspaceDir: string, accountId?: string): Promise<void>;
41
+ //# sourceMappingURL=pairing-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairing-service.d.ts","sourceRoot":"","sources":["../src/pairing-service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,gGAAgG;AAChG,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQrD;AAED,MAAM,MAAM,qBAAqB,GAC7B,MAAM,GACN,cAAc,GACd,gBAAgB,GAChB,WAAW,GACX,cAAc,GACd,SAAS,GACT,OAAO,CAAC;AAEZ,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,aAAa,GAAG,iBAAiB,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAChD;AAED,qBAAa,sBAAsB;IACjC,OAAO,CAAC,MAAM,CAA6E;IAC3F,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAK;IACrC,OAAO,CAAC,YAAY,CAA8C;gBAEtD,OAAO,EAAE,sBAAsB;IAIrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuG5B,IAAI,IAAI,IAAI;IAaZ,SAAS,IAAI,qBAAqB;IAIlC,OAAO,CAAC,SAAS;CAQlB;AAED,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,SAAY,GAAG,OAAO,CAGvF;AAED,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,SAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA8D/F"}
@@ -0,0 +1,116 @@
1
+ import { type IAgentRuntime, type Memory, Service, type UUID } from "@elizaos/core";
2
+ import type { WhatsAppMessageResponse, WhatsAppWebhookEvent } from "./types";
3
+ type RuntimeServiceConfig = {
4
+ accountId: string;
5
+ name?: string;
6
+ transport: "baileys";
7
+ authDir: string;
8
+ dmPolicy?: "open" | "allowlist" | "pairing" | "disabled";
9
+ groupPolicy?: "open" | "allowlist" | "disabled";
10
+ allowFrom?: string[];
11
+ groupAllowFrom?: string[];
12
+ } | {
13
+ accountId: string;
14
+ name?: string;
15
+ transport: "cloudapi";
16
+ accessToken: string;
17
+ phoneNumberId: string;
18
+ businessAccountId?: string;
19
+ webhookVerifyToken?: string;
20
+ apiVersion?: string;
21
+ dmPolicy?: "open" | "allowlist" | "pairing" | "disabled";
22
+ groupPolicy?: "open" | "allowlist" | "disabled";
23
+ allowFrom?: string[];
24
+ groupAllowFrom?: string[];
25
+ };
26
+ type RuntimeSendHandler = Parameters<IAgentRuntime["registerSendHandler"]>[1];
27
+ type ConnectorTargetInfo = Parameters<RuntimeSendHandler>[1];
28
+ type MessageConnectorRegistration = Parameters<IAgentRuntime["registerMessageConnector"]>[0];
29
+ type MessageConnectorQueryContext = Parameters<NonNullable<MessageConnectorRegistration["resolveTargets"]>>[1];
30
+ type ConnectorFetchMessagesParams = {
31
+ target?: ConnectorTargetInfo;
32
+ limit?: number;
33
+ before?: string;
34
+ after?: string;
35
+ channelId?: string;
36
+ roomId?: UUID;
37
+ };
38
+ type ConnectorSearchMessagesParams = ConnectorFetchMessagesParams & {
39
+ query?: string;
40
+ };
41
+ type ConnectorReactionParams = {
42
+ target?: ConnectorTargetInfo;
43
+ channelId?: string;
44
+ roomId?: UUID;
45
+ messageId?: string;
46
+ emoji?: string;
47
+ remove?: boolean;
48
+ };
49
+ type ConnectorUserLookupParams = {
50
+ userId?: string;
51
+ username?: string;
52
+ handle?: string;
53
+ query?: string;
54
+ };
55
+ type KnownWhatsAppTarget = {
56
+ accountId: string;
57
+ chatId: string;
58
+ senderId: string;
59
+ label: string;
60
+ isGroup: boolean;
61
+ lastMessageAt: number;
62
+ roomId?: UUID;
63
+ };
64
+ export declare class WhatsAppConnectorService extends Service {
65
+ static serviceType: string;
66
+ protected runtime: IAgentRuntime;
67
+ capabilityDescription: string;
68
+ connected: boolean;
69
+ phoneNumber: string | null;
70
+ private defaultAccountId;
71
+ private clients;
72
+ private configs;
73
+ private phoneNumbers;
74
+ private client;
75
+ config: RuntimeServiceConfig | undefined;
76
+ private knownTargets;
77
+ constructor(runtime?: IAgentRuntime);
78
+ resolveAccountId(accountId?: string | null): string;
79
+ private getClientForAccount;
80
+ private getConfigForAccount;
81
+ private getConnectorAccountIds;
82
+ private targetKey;
83
+ private roomIdFor;
84
+ private entityIdFor;
85
+ private worldIdFor;
86
+ private metadataMatchesAccount;
87
+ static start(runtime: IAgentRuntime): Promise<WhatsAppConnectorService>;
88
+ static registerSendHandlers(runtime: IAgentRuntime, service: WhatsAppConnectorService): void;
89
+ initialize(): Promise<void>;
90
+ stop(): Promise<void>;
91
+ handleWebhook(event: WhatsAppWebhookEvent): Promise<void>;
92
+ verifyWebhook(mode: string, token: string, challenge: string, accountId?: string): string | null;
93
+ private resolveWebhookAccountId;
94
+ private bindClientEvents;
95
+ private handleNormalizedMessage;
96
+ private handleIncomingWebhookMessage;
97
+ private processIncomingMessage;
98
+ private sendTextMessage;
99
+ sendMessage(message: {
100
+ accountId?: string;
101
+ type: "text";
102
+ to: string;
103
+ content: string;
104
+ replyToMessageId?: string;
105
+ }): Promise<WhatsAppMessageResponse>;
106
+ fetchConnectorMessages(context: MessageConnectorQueryContext, params: ConnectorFetchMessagesParams): Promise<Memory[]>;
107
+ searchConnectorMessages(context: MessageConnectorQueryContext, params: ConnectorSearchMessagesParams): Promise<Memory[]>;
108
+ reactConnectorMessage(runtime: IAgentRuntime, params: ConnectorReactionParams): Promise<void>;
109
+ getConnectorUser(_runtime: IAgentRuntime, params: ConnectorUserLookupParams): Promise<unknown>;
110
+ listKnownTargets(accountId?: string | null): KnownWhatsAppTarget[];
111
+ getKnownTarget(chatId: string, accountId?: string | null): KnownWhatsAppTarget | null;
112
+ findKnownChatByParticipant(participant: string, accountId?: string | null): KnownWhatsAppTarget | null;
113
+ private rememberTarget;
114
+ }
115
+ export {};
116
+ //# sourceMappingURL=runtime-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-service.d.ts","sourceRoot":"","sources":["../src/runtime-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * WhatsApp pairing service — manages Baileys sessions for QR code authentication.
3
+ *
4
+ * This service is separate from `@elizaos/plugin-whatsapp` because the plugin
5
+ * initializes during runtime startup (too late for interactive QR flow).
6
+ * Once pairing succeeds, the auth state is persisted to disk so the plugin
7
+ * can reconnect automatically on subsequent startups.
8
+ */
9
+ /** Validate accountId to prevent path traversal. Only allows alphanumeric, dash, underscore. */
10
+ export declare function sanitizeAccountId(raw: string): string;
11
+ export type WhatsAppPairingStatus = "idle" | "initializing" | "waiting_for_qr" | "connected" | "disconnected" | "timeout" | "error";
12
+ export interface WhatsAppPairingEvent {
13
+ type: "whatsapp-qr" | "whatsapp-status";
14
+ accountId: string;
15
+ qrDataUrl?: string;
16
+ expiresInMs?: number;
17
+ status?: WhatsAppPairingStatus;
18
+ phoneNumber?: string;
19
+ error?: string;
20
+ }
21
+ export interface WhatsAppPairingOptions {
22
+ authDir: string;
23
+ accountId: string;
24
+ onEvent: (event: WhatsAppPairingEvent) => void;
25
+ }
26
+ export declare class WhatsAppPairingSession {
27
+ private socket;
28
+ private status;
29
+ private options;
30
+ private qrAttempts;
31
+ private readonly MAX_QR_ATTEMPTS;
32
+ private restartTimer;
33
+ constructor(options: WhatsAppPairingOptions);
34
+ start(): Promise<void>;
35
+ stop(): void;
36
+ getStatus(): WhatsAppPairingStatus;
37
+ private setStatus;
38
+ }
39
+ export declare function whatsappAuthExists(workspaceDir: string, accountId?: string): boolean;
40
+ export declare function whatsappLogout(workspaceDir: string, accountId?: string): Promise<void>;
41
+ //# sourceMappingURL=whatsapp-pairing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whatsapp-pairing.d.ts","sourceRoot":"","sources":["../../src/services/whatsapp-pairing.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,gGAAgG;AAChG,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQrD;AAED,MAAM,MAAM,qBAAqB,GAC7B,MAAM,GACN,cAAc,GACd,gBAAgB,GAChB,WAAW,GACX,cAAc,GACd,SAAS,GACT,OAAO,CAAC;AAEZ,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,aAAa,GAAG,iBAAiB,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAChD;AAED,qBAAa,sBAAsB;IACjC,OAAO,CAAC,MAAM,CAA6E;IAC3F,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAK;IACrC,OAAO,CAAC,YAAY,CAA8C;gBAEtD,OAAO,EAAE,sBAAsB;IAIrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuG5B,IAAI,IAAI,IAAI;IAaZ,SAAS,IAAI,qBAAqB;IAIlC,OAAO,CAAC,SAAS;CAQlB;AAED,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,SAAY,GAAG,OAAO,CAGvF;AAED,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,SAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA8D/F"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * WhatsApp setup HTTP routes.
3
+ *
4
+ * Provides QR-code pairing, status, disconnect, and webhook endpoints:
5
+ *
6
+ * GET /api/whatsapp/webhook Meta webhook verification
7
+ * POST /api/whatsapp/webhook Meta webhook event delivery
8
+ * POST /api/whatsapp/pair Start QR pairing session
9
+ * GET /api/whatsapp/status Check connection / pairing status
10
+ * POST /api/whatsapp/pair/stop Stop active pairing session
11
+ * POST /api/whatsapp/disconnect Logout + remove auth state
12
+ *
13
+ * These routes are registered with `rawPath: true` so they mount at their
14
+ * legacy paths without the plugin-name prefix.
15
+ */
16
+ import type { Route } from "@elizaos/core";
17
+ /**
18
+ * Plugin routes for WhatsApp setup and webhooks.
19
+ * Registered with `rawPath: true` to preserve legacy `/api/whatsapp/*` paths.
20
+ */
21
+ export declare const whatsappSetupRoutes: Route[];
22
+ /**
23
+ * Stop all active pairing sessions. Called during shutdown cleanup.
24
+ */
25
+ export declare function stopAllPairingSessions(): void;
26
+ //# sourceMappingURL=setup-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-routes.d.ts","sourceRoot":"","sources":["../src/setup-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAiB,KAAK,EAA+B,MAAM,eAAe,CAAC;AA6XvF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,EAyCtC,CAAC;AAEF;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAS7C"}
@@ -0,0 +1,370 @@
1
+ export type WhatsAppConfig = CloudAPIConfig | BaileysConfig;
2
+ export interface CloudAPIConfig {
3
+ authMethod?: "cloudapi";
4
+ accessToken: string;
5
+ phoneNumberId: string;
6
+ webhookVerifyToken?: string;
7
+ businessAccountId?: string;
8
+ apiVersion?: string;
9
+ }
10
+ export interface BaileysConfig {
11
+ authMethod?: "baileys";
12
+ authDir: string;
13
+ printQRInTerminal?: boolean;
14
+ sessionPath?: string;
15
+ }
16
+ /**
17
+ * Message types supported by WhatsApp Cloud API.
18
+ */
19
+ export type WhatsAppMessageType = "text" | "template" | "image" | "audio" | "video" | "document" | "sticker" | "location" | "contacts" | "interactive" | "reaction";
20
+ export interface WhatsAppMessage {
21
+ type: WhatsAppMessageType;
22
+ to: string;
23
+ content: string | WhatsAppTemplate | WhatsAppMediaMessage | WhatsAppInteractiveMessage | WhatsAppReactionMessage | WhatsAppLocationMessage;
24
+ replyToMessageId?: string;
25
+ }
26
+ export interface WhatsAppTemplate {
27
+ name: string;
28
+ language: {
29
+ code: string;
30
+ };
31
+ components?: Array<{
32
+ type: string;
33
+ parameters: Array<{
34
+ type: string;
35
+ text?: string;
36
+ image?: {
37
+ link: string;
38
+ };
39
+ document?: {
40
+ link: string;
41
+ filename?: string;
42
+ };
43
+ video?: {
44
+ link: string;
45
+ };
46
+ }>;
47
+ }>;
48
+ }
49
+ /**
50
+ * Media message content.
51
+ */
52
+ export interface WhatsAppMediaMessage {
53
+ link?: string;
54
+ id?: string;
55
+ caption?: string;
56
+ filename?: string;
57
+ mimeType?: string;
58
+ }
59
+ /**
60
+ * Reaction message content.
61
+ */
62
+ export interface WhatsAppReactionMessage {
63
+ messageId: string;
64
+ emoji: string;
65
+ }
66
+ /**
67
+ * Location message content.
68
+ */
69
+ export interface WhatsAppLocationMessage {
70
+ latitude: number;
71
+ longitude: number;
72
+ name?: string;
73
+ address?: string;
74
+ }
75
+ /**
76
+ * Interactive message types.
77
+ */
78
+ export type InteractiveMessageType = "button" | "list" | "product" | "product_list" | "flow";
79
+ /**
80
+ * Interactive message content.
81
+ */
82
+ export interface WhatsAppInteractiveMessage {
83
+ type: InteractiveMessageType;
84
+ header?: {
85
+ type: "text" | "image" | "video" | "document";
86
+ text?: string;
87
+ image?: {
88
+ link: string;
89
+ };
90
+ video?: {
91
+ link: string;
92
+ };
93
+ document?: {
94
+ link: string;
95
+ filename?: string;
96
+ };
97
+ };
98
+ body: {
99
+ text: string;
100
+ };
101
+ footer?: {
102
+ text: string;
103
+ };
104
+ action: WhatsAppInteractiveAction;
105
+ }
106
+ /**
107
+ * Interactive action based on message type.
108
+ */
109
+ export type WhatsAppInteractiveAction = WhatsAppButtonAction | WhatsAppListAction | WhatsAppFlowAction;
110
+ /**
111
+ * Button action for interactive messages.
112
+ */
113
+ export interface WhatsAppButtonAction {
114
+ buttons: Array<{
115
+ type: "reply";
116
+ reply: {
117
+ id: string;
118
+ title: string;
119
+ };
120
+ }>;
121
+ }
122
+ /**
123
+ * List action for interactive messages.
124
+ */
125
+ export interface WhatsAppListAction {
126
+ button: string;
127
+ sections: Array<{
128
+ title?: string;
129
+ rows: Array<{
130
+ id: string;
131
+ title: string;
132
+ description?: string;
133
+ }>;
134
+ }>;
135
+ }
136
+ /**
137
+ * Flow action for interactive messages.
138
+ */
139
+ export interface WhatsAppFlowAction {
140
+ name: "flow";
141
+ parameters: {
142
+ flow_message_version: string;
143
+ flow_token: string;
144
+ flow_id: string;
145
+ flow_cta: string;
146
+ flow_action: "navigate" | "data_exchange";
147
+ flow_action_payload?: {
148
+ screen: string;
149
+ data?: Record<string, unknown>;
150
+ };
151
+ };
152
+ }
153
+ export interface WhatsAppIncomingMessage {
154
+ from: string;
155
+ id: string;
156
+ timestamp: string;
157
+ text?: {
158
+ body: string;
159
+ };
160
+ image?: {
161
+ caption?: string;
162
+ mime_type: string;
163
+ sha256: string;
164
+ id: string;
165
+ };
166
+ video?: {
167
+ caption?: string;
168
+ mime_type: string;
169
+ sha256: string;
170
+ id: string;
171
+ };
172
+ audio?: {
173
+ mime_type: string;
174
+ sha256: string;
175
+ id: string;
176
+ voice?: boolean;
177
+ };
178
+ document?: {
179
+ caption?: string;
180
+ filename: string;
181
+ mime_type: string;
182
+ sha256: string;
183
+ id: string;
184
+ };
185
+ sticker?: {
186
+ mime_type: string;
187
+ sha256: string;
188
+ id: string;
189
+ animated?: boolean;
190
+ };
191
+ location?: {
192
+ latitude: number;
193
+ longitude: number;
194
+ name?: string;
195
+ address?: string;
196
+ };
197
+ contacts?: Array<{
198
+ name: {
199
+ formatted_name: string;
200
+ first_name?: string;
201
+ last_name?: string;
202
+ };
203
+ phones?: Array<{
204
+ phone: string;
205
+ type: string;
206
+ }>;
207
+ }>;
208
+ interactive?: {
209
+ type: "button_reply" | "list_reply" | "nfm_reply";
210
+ button_reply?: {
211
+ id: string;
212
+ title: string;
213
+ };
214
+ list_reply?: {
215
+ id: string;
216
+ title: string;
217
+ description?: string;
218
+ };
219
+ nfm_reply?: {
220
+ response_json: string;
221
+ body: string;
222
+ name: string;
223
+ };
224
+ };
225
+ reaction?: {
226
+ message_id: string;
227
+ emoji: string;
228
+ };
229
+ context?: {
230
+ from: string;
231
+ id: string;
232
+ referred_product?: {
233
+ catalog_id: string;
234
+ product_retailer_id: string;
235
+ };
236
+ };
237
+ type: string;
238
+ }
239
+ export interface WhatsAppStatusUpdate {
240
+ id: string;
241
+ status: "sent" | "delivered" | "read" | "failed";
242
+ timestamp: string;
243
+ recipient_id: string;
244
+ conversation?: {
245
+ id: string;
246
+ origin?: {
247
+ type: string;
248
+ };
249
+ expiration_timestamp?: string;
250
+ };
251
+ pricing?: {
252
+ billable: boolean;
253
+ pricing_model: string;
254
+ category: string;
255
+ };
256
+ errors?: Array<{
257
+ code: number;
258
+ title: string;
259
+ message?: string;
260
+ error_data?: {
261
+ details: string;
262
+ };
263
+ }>;
264
+ }
265
+ export interface WhatsAppWebhookEvent {
266
+ object: string;
267
+ entry: Array<{
268
+ id: string;
269
+ changes: Array<{
270
+ value: {
271
+ messaging_product: string;
272
+ metadata: {
273
+ display_phone_number: string;
274
+ phone_number_id: string;
275
+ };
276
+ statuses?: WhatsAppStatusUpdate[];
277
+ messages?: WhatsAppIncomingMessage[];
278
+ contacts?: Array<{
279
+ profile: {
280
+ name: string;
281
+ };
282
+ wa_id: string;
283
+ }>;
284
+ errors?: Array<{
285
+ code: number;
286
+ title: string;
287
+ message?: string;
288
+ error_data?: {
289
+ details: string;
290
+ };
291
+ }>;
292
+ };
293
+ field: string;
294
+ }>;
295
+ }>;
296
+ }
297
+ export interface WhatsAppMessageResponse {
298
+ messaging_product: string;
299
+ contacts: Array<{
300
+ input: string;
301
+ wa_id: string;
302
+ }>;
303
+ messages: Array<{
304
+ id: string;
305
+ message_status?: string;
306
+ }>;
307
+ }
308
+ export interface QRCodeData {
309
+ terminal: string;
310
+ dataURL: string;
311
+ raw: string;
312
+ }
313
+ export type ConnectionStatus = "connecting" | "open" | "close";
314
+ export interface NormalizedMessage {
315
+ id: string;
316
+ from: string;
317
+ timestamp: number;
318
+ type: "text" | "image" | "audio" | "video" | "document";
319
+ content: string;
320
+ chatId?: string;
321
+ senderId?: string;
322
+ replyToId?: string;
323
+ }
324
+ /**
325
+ * Send reaction parameters.
326
+ */
327
+ export interface SendReactionParams {
328
+ to: string;
329
+ messageId: string;
330
+ emoji: string;
331
+ }
332
+ /**
333
+ * Send reaction result.
334
+ */
335
+ export interface SendReactionResult {
336
+ success: boolean;
337
+ messageId?: string;
338
+ error?: string;
339
+ }
340
+ /**
341
+ * WhatsApp event types.
342
+ */
343
+ export declare enum WhatsAppEventType {
344
+ MESSAGE_RECEIVED = "WHATSAPP_MESSAGE_RECEIVED",
345
+ MESSAGE_SENT = "WHATSAPP_MESSAGE_SENT",
346
+ MESSAGE_DELIVERED = "WHATSAPP_MESSAGE_DELIVERED",
347
+ MESSAGE_READ = "WHATSAPP_MESSAGE_READ",
348
+ MESSAGE_FAILED = "WHATSAPP_MESSAGE_FAILED",
349
+ REACTION_RECEIVED = "WHATSAPP_REACTION_RECEIVED",
350
+ REACTION_SENT = "WHATSAPP_REACTION_SENT",
351
+ INTERACTIVE_REPLY = "WHATSAPP_INTERACTIVE_REPLY",
352
+ WEBHOOK_VERIFIED = "WHATSAPP_WEBHOOK_VERIFIED"
353
+ }
354
+ /**
355
+ * Common WhatsApp reaction emojis.
356
+ */
357
+ export declare const WHATSAPP_REACTIONS: {
358
+ readonly THUMBS_UP: "👍";
359
+ readonly THUMBS_DOWN: "👎";
360
+ readonly HEART: "❤️";
361
+ readonly LAUGHING: "😂";
362
+ readonly SURPRISED: "😮";
363
+ readonly SAD: "😢";
364
+ readonly PRAYING: "🙏";
365
+ readonly CLAPPING: "👏";
366
+ readonly FIRE: "🔥";
367
+ readonly CELEBRATION: "🎉";
368
+ };
369
+ export type WhatsAppReactionEmoji = (typeof WHATSAPP_REACTIONS)[keyof typeof WHATSAPP_REACTIONS];
370
+ //# sourceMappingURL=types.d.ts.map