@kangwifi-pro/waliwa 1.0.0

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 (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +600 -0
  3. package/dist/advanced/features.d.ts +211 -0
  4. package/dist/advanced/features.d.ts.map +1 -0
  5. package/dist/advanced/features.js +671 -0
  6. package/dist/advanced/features.js.map +1 -0
  7. package/dist/auth/auth-state.d.ts +89 -0
  8. package/dist/auth/auth-state.d.ts.map +1 -0
  9. package/dist/auth/auth-state.js +330 -0
  10. package/dist/auth/auth-state.js.map +1 -0
  11. package/dist/auth/pairing-code.d.ts +78 -0
  12. package/dist/auth/pairing-code.d.ts.map +1 -0
  13. package/dist/auth/pairing-code.js +191 -0
  14. package/dist/auth/pairing-code.js.map +1 -0
  15. package/dist/auth/qr-code.d.ts +60 -0
  16. package/dist/auth/qr-code.d.ts.map +1 -0
  17. package/dist/auth/qr-code.js +151 -0
  18. package/dist/auth/qr-code.js.map +1 -0
  19. package/dist/calls/handler.d.ts +61 -0
  20. package/dist/calls/handler.d.ts.map +1 -0
  21. package/dist/calls/handler.js +117 -0
  22. package/dist/calls/handler.js.map +1 -0
  23. package/dist/core/binary.d.ts +74 -0
  24. package/dist/core/binary.d.ts.map +1 -0
  25. package/dist/core/binary.js +448 -0
  26. package/dist/core/binary.js.map +1 -0
  27. package/dist/core/crypto.d.ts +60 -0
  28. package/dist/core/crypto.d.ts.map +1 -0
  29. package/dist/core/crypto.js +170 -0
  30. package/dist/core/crypto.js.map +1 -0
  31. package/dist/core/noise.d.ts +106 -0
  32. package/dist/core/noise.d.ts.map +1 -0
  33. package/dist/core/noise.js +307 -0
  34. package/dist/core/noise.js.map +1 -0
  35. package/dist/events/emitter.d.ts +44 -0
  36. package/dist/events/emitter.d.ts.map +1 -0
  37. package/dist/events/emitter.js +79 -0
  38. package/dist/events/emitter.js.map +1 -0
  39. package/dist/features/index.d.ts +342 -0
  40. package/dist/features/index.d.ts.map +1 -0
  41. package/dist/features/index.js +755 -0
  42. package/dist/features/index.js.map +1 -0
  43. package/dist/fixes/index.d.ts +333 -0
  44. package/dist/fixes/index.d.ts.map +1 -0
  45. package/dist/fixes/index.js +762 -0
  46. package/dist/fixes/index.js.map +1 -0
  47. package/dist/groups/management.d.ts +86 -0
  48. package/dist/groups/management.d.ts.map +1 -0
  49. package/dist/groups/management.js +443 -0
  50. package/dist/groups/management.js.map +1 -0
  51. package/dist/index.d.ts +65 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +236 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/messages/media.d.ts +93 -0
  56. package/dist/messages/media.d.ts.map +1 -0
  57. package/dist/messages/media.js +252 -0
  58. package/dist/messages/media.js.map +1 -0
  59. package/dist/messages/message-encoder.d.ts +70 -0
  60. package/dist/messages/message-encoder.d.ts.map +1 -0
  61. package/dist/messages/message-encoder.js +453 -0
  62. package/dist/messages/message-encoder.js.map +1 -0
  63. package/dist/messages/send.d.ts +101 -0
  64. package/dist/messages/send.d.ts.map +1 -0
  65. package/dist/messages/send.js +409 -0
  66. package/dist/messages/send.js.map +1 -0
  67. package/dist/recovery/index.d.ts +125 -0
  68. package/dist/recovery/index.d.ts.map +1 -0
  69. package/dist/recovery/index.js +584 -0
  70. package/dist/recovery/index.js.map +1 -0
  71. package/dist/skdm/index.d.ts +220 -0
  72. package/dist/skdm/index.d.ts.map +1 -0
  73. package/dist/skdm/index.js +600 -0
  74. package/dist/skdm/index.js.map +1 -0
  75. package/dist/socket/hybrid.d.ts +118 -0
  76. package/dist/socket/hybrid.d.ts.map +1 -0
  77. package/dist/socket/hybrid.js +352 -0
  78. package/dist/socket/hybrid.js.map +1 -0
  79. package/dist/socket/wa-socket.d.ts +300 -0
  80. package/dist/socket/wa-socket.d.ts.map +1 -0
  81. package/dist/socket/wa-socket.js +1094 -0
  82. package/dist/socket/wa-socket.js.map +1 -0
  83. package/dist/socket/ws-socket.d.ts +96 -0
  84. package/dist/socket/ws-socket.d.ts.map +1 -0
  85. package/dist/socket/ws-socket.js +302 -0
  86. package/dist/socket/ws-socket.js.map +1 -0
  87. package/dist/types/index.d.ts +444 -0
  88. package/dist/types/index.d.ts.map +1 -0
  89. package/dist/types/index.js +7 -0
  90. package/dist/types/index.js.map +1 -0
  91. package/dist/utils/jid.d.ts +46 -0
  92. package/dist/utils/jid.d.ts.map +1 -0
  93. package/dist/utils/jid.js +152 -0
  94. package/dist/utils/jid.js.map +1 -0
  95. package/dist/utils/logger.d.ts +45 -0
  96. package/dist/utils/logger.d.ts.map +1 -0
  97. package/dist/utils/logger.js +79 -0
  98. package/dist/utils/logger.js.map +1 -0
  99. package/dist/utils/retry.d.ts +43 -0
  100. package/dist/utils/retry.d.ts.map +1 -0
  101. package/dist/utils/retry.js +175 -0
  102. package/dist/utils/retry.js.map +1 -0
  103. package/docs/API.md +745 -0
  104. package/docs/ARCHITECTURE.md +307 -0
  105. package/docs/BAILEYS_FIXES.md +360 -0
  106. package/docs/FEATURES.md +532 -0
  107. package/docs/PROTOCOL.md +489 -0
  108. package/docs/RECOVERY.md +409 -0
  109. package/docs/SKDM.md +233 -0
  110. package/examples/ai-bot/index.ts +479 -0
  111. package/examples/ai-bot/package.json +17 -0
  112. package/examples/echo-bot/index.ts +171 -0
  113. package/examples/echo-bot/package.json +18 -0
  114. package/examples/group-bot/index.ts +557 -0
  115. package/examples/group-bot/package.json +17 -0
  116. package/examples/rest-gateway/index.ts +499 -0
  117. package/examples/rest-gateway/package.json +19 -0
  118. package/package.json +75 -0
  119. package/src/advanced/features.ts +817 -0
  120. package/src/auth/auth-state.ts +342 -0
  121. package/src/auth/pairing-code.ts +246 -0
  122. package/src/auth/qr-code.ts +191 -0
  123. package/src/calls/handler.ts +153 -0
  124. package/src/core/binary.ts +464 -0
  125. package/src/core/crypto.ts +189 -0
  126. package/src/core/noise.ts +406 -0
  127. package/src/events/emitter.ts +88 -0
  128. package/src/features/index.ts +921 -0
  129. package/src/fixes/index.ts +882 -0
  130. package/src/groups/management.ts +497 -0
  131. package/src/index.ts +274 -0
  132. package/src/messages/media.ts +372 -0
  133. package/src/messages/message-encoder.ts +520 -0
  134. package/src/messages/send.ts +521 -0
  135. package/src/recovery/index.ts +704 -0
  136. package/src/skdm/index.ts +693 -0
  137. package/src/socket/hybrid.ts +414 -0
  138. package/src/socket/wa-socket.ts +1347 -0
  139. package/src/socket/ws-socket.ts +355 -0
  140. package/src/types/index.ts +457 -0
  141. package/src/utils/jid.ts +156 -0
  142. package/src/utils/logger.ts +84 -0
  143. package/src/utils/retry.ts +205 -0
  144. package/tsconfig.json +30 -0
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Waliwa - Mobile API socket layer
3
+ *
4
+ * Companion device pairing via phone number + code (no QR scan needed).
5
+ * Mengikuti WhatsApp Mobile API registration flow:
6
+ * 1. Request pairing code untuk phone number
7
+ * 2. User input code di WA mobile app
8
+ * 3. Server pair device, return identity keys
9
+ * 4. Switch ke WA Web protocol untuk ongoing communication
10
+ *
11
+ * Hybrid approach: pairing via Mobile API, communication via WA Web WS
12
+ */
13
+ import { EventEmitter } from 'events';
14
+ import { WAWebSocket } from './ws-socket.js';
15
+ import type { AuthenticationCreds, PairingCodeResult, WALogger, WaliwaConfig } from '../types/index.js';
16
+ export interface MobileSocketOptions {
17
+ phoneNumber: string;
18
+ creds: AuthenticationCreds;
19
+ logger?: WALogger;
20
+ /** Browser identification */
21
+ browser?: [string, string, string];
22
+ /** WA WebSocket URL setelah pairing */
23
+ waWsUrl?: string;
24
+ connectTimeoutMs?: number;
25
+ ramLevel?: 1 | 2 | 3;
26
+ }
27
+ /**
28
+ * Mobile API socket - handles companion device pairing via phone number
29
+ *
30
+ * Flow:
31
+ * 1. connect() - init WA WebSocket
32
+ * 2. requestPairing() - generate pairing code untuk user
33
+ * 3. wait for user to input code di mobile app
34
+ * 4. server sends pairing confirmation
35
+ * 5. switch ke normal WA Web communication
36
+ */
37
+ export declare class MobileAPISocket extends EventEmitter {
38
+ private phoneNumber;
39
+ private creds;
40
+ private logger;
41
+ private browser;
42
+ private waWsUrl;
43
+ private connectTimeoutMs;
44
+ private ramLevel;
45
+ private ws;
46
+ private pairingExpiry;
47
+ private isPairing;
48
+ constructor(opts: MobileSocketOptions);
49
+ /**
50
+ * Connect dan start pairing flow
51
+ */
52
+ connect(): Promise<PairingCodeResult>;
53
+ /**
54
+ * Send pairing request ke server
55
+ */
56
+ private sendPairingRequest;
57
+ /**
58
+ * Handle incoming data
59
+ */
60
+ private handleIncomingData;
61
+ /**
62
+ * Send raw data via WebSocket
63
+ */
64
+ send(data: Uint8Array): void;
65
+ /**
66
+ * Get underlying WA WebSocket (untuk pas-pairing switch ke WA Web mode)
67
+ */
68
+ getWebSocket(): WAWebSocket | null;
69
+ /**
70
+ * Close socket
71
+ */
72
+ close(): Promise<void>;
73
+ isPairingInProgress(): boolean;
74
+ }
75
+ export interface HybridSocketOptions extends WaliwaConfig {
76
+ /** Primary mode: 'web' (QR) atau 'mobile' (pairing code) */
77
+ primaryMode?: 'web' | 'mobile';
78
+ /** Phone number (required jika primaryMode='mobile') */
79
+ phoneNumber?: string;
80
+ /** Auto-fallback ke other mode jika primary gagal */
81
+ autoFallback?: boolean;
82
+ }
83
+ /**
84
+ * Hybrid socket manager - otomatis switch antara WA Web (QR) dan Mobile API (pairing)
85
+ *
86
+ * - Primary mode: coba connect dengan mode utama
87
+ * - Fallback: jika gagal setelah maxRetries, switch ke mode lain
88
+ * - Mode switching transparent ke caller
89
+ */
90
+ export declare class HybridSocketManager extends EventEmitter {
91
+ private opts;
92
+ private currentMode;
93
+ private currentSocket;
94
+ private retryCount;
95
+ constructor(opts: HybridSocketOptions);
96
+ /**
97
+ * Connect dengan hybrid mode
98
+ */
99
+ connect(): Promise<any>;
100
+ /**
101
+ * Handle error dari current socket - mungkin switch mode
102
+ */
103
+ private handleModeError;
104
+ /**
105
+ * Send data via current socket
106
+ */
107
+ send(data: Uint8Array): void;
108
+ /**
109
+ * Close socket
110
+ */
111
+ close(): Promise<void>;
112
+ /**
113
+ * Get current mode
114
+ */
115
+ getCurrentMode(): 'web' | 'mobile';
116
+ private logger;
117
+ }
118
+ //# sourceMappingURL=hybrid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid.d.ts","sourceRoot":"","sources":["../../src/socket/hybrid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAM7C,OAAO,KAAK,EACV,mBAAmB,EACnB,iBAAiB,EACjB,QAAQ,EACR,YAAY,EAEb,MAAM,mBAAmB,CAAC;AAI3B,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAY;IAE5B,OAAO,CAAC,EAAE,CAA4B;IACtC,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,SAAS,CAAkB;gBAEvB,IAAI,EAAE,mBAAmB;IAWrC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,iBAAiB,CAAC;IA+C3C;;OAEG;YACW,kBAAkB;IA6BhC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA2C1B;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAO5B;;OAEG;IACH,YAAY,IAAI,WAAW,GAAG,IAAI;IAIlC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5B,mBAAmB,IAAI,OAAO;CAG/B;AAID,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACvD,4DAA4D;IAC5D,WAAW,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC/B,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,YAAY;IACnD,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,WAAW,CAAmB;IACtC,OAAO,CAAC,aAAa,CAA8C;IACnE,OAAO,CAAC,UAAU,CAAa;gBAEnB,IAAI,EAAE,mBAAmB;IAwBrC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC;IAoD7B;;OAEG;IACH,OAAO,CAAC,eAAe;IA4BvB;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAW5B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B;;OAEG;IACH,cAAc,IAAI,KAAK,GAAG,QAAQ;IAIlC,OAAO,CAAC,MAAM;CAGf"}
@@ -0,0 +1,352 @@
1
+ "use strict";
2
+ /**
3
+ * Waliwa - Mobile API socket layer
4
+ *
5
+ * Companion device pairing via phone number + code (no QR scan needed).
6
+ * Mengikuti WhatsApp Mobile API registration flow:
7
+ * 1. Request pairing code untuk phone number
8
+ * 2. User input code di WA mobile app
9
+ * 3. Server pair device, return identity keys
10
+ * 4. Switch ke WA Web protocol untuk ongoing communication
11
+ *
12
+ * Hybrid approach: pairing via Mobile API, communication via WA Web WS
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.HybridSocketManager = exports.MobileAPISocket = void 0;
16
+ const events_1 = require("events");
17
+ const ws_socket_js_1 = require("./ws-socket.js");
18
+ const binary_js_1 = require("../core/binary.js");
19
+ const pairing_code_js_1 = require("../auth/pairing-code.js");
20
+ const logger_js_1 = require("../utils/logger.js");
21
+ /**
22
+ * Mobile API socket - handles companion device pairing via phone number
23
+ *
24
+ * Flow:
25
+ * 1. connect() - init WA WebSocket
26
+ * 2. requestPairing() - generate pairing code untuk user
27
+ * 3. wait for user to input code di mobile app
28
+ * 4. server sends pairing confirmation
29
+ * 5. switch ke normal WA Web communication
30
+ */
31
+ class MobileAPISocket extends events_1.EventEmitter {
32
+ phoneNumber;
33
+ creds;
34
+ logger;
35
+ browser;
36
+ waWsUrl;
37
+ connectTimeoutMs;
38
+ ramLevel;
39
+ ws = null;
40
+ pairingExpiry = null;
41
+ isPairing = false;
42
+ constructor(opts) {
43
+ super();
44
+ this.phoneNumber = opts.phoneNumber;
45
+ this.creds = opts.creds;
46
+ this.logger = opts.logger ?? new logger_js_1.SilentLogger();
47
+ this.browser = opts.browser ?? ['Waliwa', 'WA', '1.0.0'];
48
+ this.waWsUrl = opts.waWsUrl ?? 'wss://web.whatsapp.com/ws/chat';
49
+ this.connectTimeoutMs = opts.connectTimeoutMs ?? 30000;
50
+ this.ramLevel = opts.ramLevel ?? 2;
51
+ }
52
+ /**
53
+ * Connect dan start pairing flow
54
+ */
55
+ async connect() {
56
+ this.logger.info(`Starting Mobile API pairing untuk phone: ${this.phoneNumber}`);
57
+ // Init WA WebSocket dengan Noise handshake
58
+ this.ws = new ws_socket_js_1.WAWebSocket({
59
+ url: this.waWsUrl,
60
+ logger: this.logger,
61
+ browser: this.browser,
62
+ connectTimeoutMs: this.connectTimeoutMs,
63
+ noiseKey: this.creds.noiseKey,
64
+ ramLevel: this.ramLevel
65
+ });
66
+ // Listen for incoming nodes
67
+ this.ws.on('message', (data) => this.handleIncomingData(data));
68
+ this.ws.on('close', (code, reason) => {
69
+ this.logger.warn(`Mobile socket closed: ${code} ${reason}`);
70
+ this.emit('close', code, reason);
71
+ });
72
+ this.ws.on('error', (err) => {
73
+ this.logger.error(`Mobile socket error: ${err.message}`);
74
+ this.emit('error', err);
75
+ });
76
+ await this.ws.connect();
77
+ this.logger.info('WebSocket connected, generating pairing code');
78
+ // Generate pairing code
79
+ const pairingResult = (0, pairing_code_js_1.generatePairingCode)(this.phoneNumber, this.creds, this.logger);
80
+ // Setup expiry
81
+ this.pairingExpiry = new pairing_code_js_1.PairingCodeExpiry(pairingResult.expiresAt, () => {
82
+ this.logger.warn('Pairing code expired');
83
+ this.emit('pairing:expired');
84
+ });
85
+ this.pairingExpiry.start();
86
+ // Send pairing request ke server
87
+ await this.sendPairingRequest(pairingResult);
88
+ this.isPairing = true;
89
+ return pairingResult;
90
+ }
91
+ /**
92
+ * Send pairing request ke server
93
+ */
94
+ async sendPairingRequest(pairing) {
95
+ if (!this.creds.pairingKey) {
96
+ throw new Error('No pairing key in creds');
97
+ }
98
+ const pairNode = {
99
+ tag: 'iq',
100
+ attrs: {
101
+ type: 'set',
102
+ to: 's.whatsapp.net',
103
+ id: `pair-${Date.now()}`
104
+ },
105
+ content: [
106
+ {
107
+ tag: 'pair',
108
+ attrs: {
109
+ code: pairing.code.replace('-', ''),
110
+ phone: pairing.phoneNumber,
111
+ pubkey: Buffer.from(this.creds.pairingKey.public).toString('base64'),
112
+ platform: this.browser[0]
113
+ }
114
+ }
115
+ ]
116
+ };
117
+ this.ws.send((0, binary_js_1.encodeBinaryNode)(pairNode));
118
+ this.logger.debug(`Pairing request sent for ${pairing.phoneNumber}`);
119
+ }
120
+ /**
121
+ * Handle incoming data
122
+ */
123
+ handleIncomingData(data) {
124
+ try {
125
+ const node = (0, binary_js_1.decodeBinaryNode)(data);
126
+ if (!node)
127
+ return;
128
+ // Pairing response
129
+ if (node.tag === 'iq' && node.attrs?.id?.startsWith('pair-')) {
130
+ const result = (0, pairing_code_js_1.parsePairingResult)(node);
131
+ if (result.success) {
132
+ this.logger.info(`Pairing successful: paired with ${result.jid}`);
133
+ // Update creds
134
+ this.creds.registered = true;
135
+ if (result.jid) {
136
+ this.creds.me = result.jid;
137
+ }
138
+ if (result.identityKey) {
139
+ // Store server-side identity
140
+ this.logger.debug('Got server identity key');
141
+ }
142
+ if (this.pairingExpiry) {
143
+ this.pairingExpiry.cancel();
144
+ this.pairingExpiry = null;
145
+ }
146
+ this.isPairing = false;
147
+ this.emit('paired', result);
148
+ this.emit('connection.update', {
149
+ connection: 'open',
150
+ isNewLogin: true
151
+ });
152
+ }
153
+ else {
154
+ this.logger.error(`Pairing failed: ${result.error}`);
155
+ this.emit('pairing:error', new Error(result.error));
156
+ }
157
+ return;
158
+ }
159
+ // Re-emit other nodes untuk processing selanjutnya
160
+ this.emit('message', node);
161
+ }
162
+ catch (err) {
163
+ this.logger.error(`Failed to process data: ${err.message}`);
164
+ }
165
+ }
166
+ /**
167
+ * Send raw data via WebSocket
168
+ */
169
+ send(data) {
170
+ if (!this.ws || !this.ws.isConnected()) {
171
+ throw new Error('Socket not connected');
172
+ }
173
+ this.ws.send(data);
174
+ }
175
+ /**
176
+ * Get underlying WA WebSocket (untuk pas-pairing switch ke WA Web mode)
177
+ */
178
+ getWebSocket() {
179
+ return this.ws;
180
+ }
181
+ /**
182
+ * Close socket
183
+ */
184
+ async close() {
185
+ if (this.pairingExpiry) {
186
+ this.pairingExpiry.cancel();
187
+ this.pairingExpiry = null;
188
+ }
189
+ if (this.ws) {
190
+ this.ws.close();
191
+ this.ws = null;
192
+ }
193
+ this.isPairing = false;
194
+ }
195
+ isPairingInProgress() {
196
+ return this.isPairing;
197
+ }
198
+ }
199
+ exports.MobileAPISocket = MobileAPISocket;
200
+ /**
201
+ * Hybrid socket manager - otomatis switch antara WA Web (QR) dan Mobile API (pairing)
202
+ *
203
+ * - Primary mode: coba connect dengan mode utama
204
+ * - Fallback: jika gagal setelah maxRetries, switch ke mode lain
205
+ * - Mode switching transparent ke caller
206
+ */
207
+ class HybridSocketManager extends events_1.EventEmitter {
208
+ opts;
209
+ currentMode;
210
+ currentSocket = null;
211
+ retryCount = 0;
212
+ constructor(opts) {
213
+ super();
214
+ this.opts = {
215
+ ...opts,
216
+ primaryMode: opts.primaryMode ?? (opts.mobile ? 'mobile' : 'web'),
217
+ autoFallback: opts.autoFallback ?? true,
218
+ phoneNumber: opts.phoneNumber ?? '',
219
+ wsURL: opts.wsURL ?? 'wss://web.whatsapp.com/ws/chat',
220
+ connectTimeoutMs: opts.connectTimeoutMs ?? 20000,
221
+ keepAliveIntervalMs: opts.keepAliveIntervalMs ?? 20000,
222
+ ramOptimizationLevel: opts.ramOptimizationLevel ?? 2,
223
+ browser: opts.browser ?? ['Waliwa', 'WA', '1.0.0'],
224
+ printQRInTerminal: opts.printQRInTerminal ?? false,
225
+ mobile: opts.mobile ?? false,
226
+ syncFullHistory: opts.syncFullHistory ?? false,
227
+ maxMsgRetryCount: opts.maxMsgRetryCount ?? 5,
228
+ maxReconnectAttempts: opts.maxReconnectAttempts ?? 10,
229
+ reconnectInterval: opts.reconnectInterval ?? 2000,
230
+ markOnlineOnConnect: opts.markOnlineOnConnect ?? true,
231
+ fetchAgent: opts.fetchAgent
232
+ };
233
+ this.currentMode = this.opts.primaryMode;
234
+ }
235
+ /**
236
+ * Connect dengan hybrid mode
237
+ */
238
+ async connect() {
239
+ if (this.currentMode === 'mobile') {
240
+ if (!this.opts.phoneNumber) {
241
+ if (this.opts.autoFallback) {
242
+ this.logger().info('No phone number provided, falling back to QR mode');
243
+ this.currentMode = 'web';
244
+ return this.connect();
245
+ }
246
+ throw new Error('phoneNumber required untuk Mobile API mode');
247
+ }
248
+ const mobileSocket = new MobileAPISocket({
249
+ phoneNumber: this.opts.phoneNumber,
250
+ creds: this.opts.authState.creds,
251
+ logger: this.logger(),
252
+ browser: this.opts.browser,
253
+ waWsUrl: this.opts.wsURL,
254
+ connectTimeoutMs: this.opts.connectTimeoutMs,
255
+ ramLevel: this.opts.ramOptimizationLevel
256
+ });
257
+ mobileSocket.on('paired', (result) => this.emit('paired', result));
258
+ mobileSocket.on('pairing:error', (err) => this.handleModeError(err));
259
+ mobileSocket.on('pairing:expired', () => this.handleModeError(new Error('Pairing expired')));
260
+ mobileSocket.on('connection.update', (update) => this.emit('connection.update', update));
261
+ mobileSocket.on('message', (node) => this.emit('message', node));
262
+ this.currentSocket = mobileSocket;
263
+ return mobileSocket.connect();
264
+ }
265
+ else {
266
+ // Web mode
267
+ const wsSocket = new ws_socket_js_1.WAWebSocket({
268
+ url: this.opts.wsURL,
269
+ logger: this.logger(),
270
+ browser: this.opts.browser,
271
+ connectTimeoutMs: this.opts.connectTimeoutMs,
272
+ keepAliveIntervalMs: this.opts.keepAliveIntervalMs,
273
+ noiseKey: this.opts.authState.creds.noiseKey,
274
+ ramLevel: this.opts.ramOptimizationLevel
275
+ });
276
+ wsSocket.on('message', (data) => this.emit('message', data));
277
+ wsSocket.on('close', (code, reason) => {
278
+ this.emit('close', code, reason);
279
+ });
280
+ wsSocket.on('error', (err) => this.handleModeError(err));
281
+ this.currentSocket = wsSocket;
282
+ return wsSocket.connect();
283
+ }
284
+ }
285
+ /**
286
+ * Handle error dari current socket - mungkin switch mode
287
+ */
288
+ handleModeError(err) {
289
+ this.retryCount++;
290
+ this.logger().error(`Socket error (${this.currentMode} mode): ${err.message}`);
291
+ if (this.opts.autoFallback && this.retryCount >= 3) {
292
+ // Switch mode
293
+ const newMode = this.currentMode === 'web' ? 'mobile' : 'web';
294
+ this.logger().warn(`Switching from ${this.currentMode} to ${newMode} mode after ${this.retryCount} retries`);
295
+ this.currentMode = newMode;
296
+ this.retryCount = 0;
297
+ // Close current dan reconnect
298
+ if (this.currentSocket) {
299
+ if (this.currentSocket instanceof MobileAPISocket) {
300
+ this.currentSocket.close();
301
+ }
302
+ else {
303
+ this.currentSocket.close();
304
+ }
305
+ this.currentSocket = null;
306
+ }
307
+ // Reconnect dengan mode baru
308
+ this.connect().catch(reconnectErr => {
309
+ this.logger().error(`Reconnect failed: ${reconnectErr.message}`);
310
+ });
311
+ }
312
+ }
313
+ /**
314
+ * Send data via current socket
315
+ */
316
+ send(data) {
317
+ if (!this.currentSocket) {
318
+ throw new Error('No active socket');
319
+ }
320
+ if (this.currentSocket instanceof MobileAPISocket) {
321
+ this.currentSocket.send(data);
322
+ }
323
+ else {
324
+ this.currentSocket.send(data);
325
+ }
326
+ }
327
+ /**
328
+ * Close socket
329
+ */
330
+ async close() {
331
+ if (this.currentSocket) {
332
+ if (this.currentSocket instanceof MobileAPISocket) {
333
+ await this.currentSocket.close();
334
+ }
335
+ else {
336
+ this.currentSocket.close();
337
+ }
338
+ this.currentSocket = null;
339
+ }
340
+ }
341
+ /**
342
+ * Get current mode
343
+ */
344
+ getCurrentMode() {
345
+ return this.currentMode;
346
+ }
347
+ logger() {
348
+ return this.opts.logger ?? new logger_js_1.SilentLogger();
349
+ }
350
+ }
351
+ exports.HybridSocketManager = HybridSocketManager;
352
+ //# sourceMappingURL=hybrid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid.js","sourceRoot":"","sources":["../../src/socket/hybrid.ts"],"names":[],"mappings":"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"}