@kangwifi-pro/waliwa 1.1.13 → 1.1.14

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 (70) hide show
  1. package/dist/core/client-payload.d.ts +30 -0
  2. package/dist/core/client-payload.d.ts.map +1 -0
  3. package/dist/core/client-payload.js +203 -0
  4. package/dist/core/client-payload.js.map +1 -0
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.js +1 -1
  7. package/dist/socket/wa-socket.d.ts.map +1 -1
  8. package/dist/socket/wa-socket.js +3 -5
  9. package/dist/socket/wa-socket.js.map +1 -1
  10. package/dist/socket/ws-socket.d.ts +4 -1
  11. package/dist/socket/ws-socket.d.ts.map +1 -1
  12. package/dist/socket/ws-socket.js +21 -18
  13. package/dist/socket/ws-socket.js.map +1 -1
  14. package/package.json +16 -10
  15. package/proto/WAProto.proto +3344 -0
  16. package/docs/API.md +0 -745
  17. package/docs/ARCHITECTURE.md +0 -307
  18. package/docs/BAILEYS_FIXES.md +0 -360
  19. package/docs/COMMUNITY.md +0 -613
  20. package/docs/FEATURES.md +0 -532
  21. package/docs/PROTOCOL.md +0 -489
  22. package/docs/RECOVERY.md +0 -409
  23. package/docs/SKDM.md +0 -233
  24. package/examples/ai-bot/index.ts +0 -479
  25. package/examples/ai-bot/package.json +0 -17
  26. package/examples/echo-bot/index.ts +0 -171
  27. package/examples/echo-bot/package.json +0 -18
  28. package/examples/group-bot/index.ts +0 -557
  29. package/examples/group-bot/package.json +0 -17
  30. package/examples/rest-gateway/index.ts +0 -499
  31. package/examples/rest-gateway/package.json +0 -19
  32. package/src/advanced/features.ts +0 -817
  33. package/src/auth/auth-state.ts +0 -342
  34. package/src/auth/pairing-code.ts +0 -246
  35. package/src/auth/qr-code.ts +0 -191
  36. package/src/calls/handler.ts +0 -153
  37. package/src/community/audio-transcription.ts +0 -121
  38. package/src/community/bulk-operations.ts +0 -329
  39. package/src/community/community-fixes.ts +0 -771
  40. package/src/community/contacts-manager.ts +0 -282
  41. package/src/community/disappearing.ts +0 -218
  42. package/src/community/index.ts +0 -169
  43. package/src/community/live-location.ts +0 -287
  44. package/src/community/message-extras.ts +0 -523
  45. package/src/community/newsletter-extended.ts +0 -614
  46. package/src/community/privacy-manager.ts +0 -310
  47. package/src/community/profile-manager.ts +0 -402
  48. package/src/community/status-extended.ts +0 -518
  49. package/src/community/sticker-manager.ts +0 -305
  50. package/src/core/binary.ts +0 -464
  51. package/src/core/crypto.ts +0 -197
  52. package/src/core/noise.ts +0 -421
  53. package/src/events/emitter.ts +0 -88
  54. package/src/features/index.ts +0 -921
  55. package/src/fixes/index.ts +0 -882
  56. package/src/groups/management.ts +0 -497
  57. package/src/index.ts +0 -339
  58. package/src/messages/media.ts +0 -372
  59. package/src/messages/message-encoder.ts +0 -520
  60. package/src/messages/send.ts +0 -521
  61. package/src/recovery/index.ts +0 -704
  62. package/src/skdm/index.ts +0 -693
  63. package/src/socket/hybrid.ts +0 -414
  64. package/src/socket/wa-socket.ts +0 -1735
  65. package/src/socket/ws-socket.ts +0 -486
  66. package/src/types/index.ts +0 -457
  67. package/src/utils/jid.ts +0 -156
  68. package/src/utils/logger.ts +0 -84
  69. package/src/utils/retry.ts +0 -205
  70. package/tsconfig.json +0 -30
@@ -1,521 +0,0 @@
1
- /**
2
- * Waliwa - Message send/receive operations
3
- * High-level API untuk kirim dan terima pesan
4
- */
5
-
6
- import type {
7
- MessageContent,
8
- WAMessage,
9
- WAMessageKey,
10
- JIDLike,
11
- SendMessageResult,
12
- WALogger,
13
- MessageStatus
14
- } from '../types/index.js';
15
- import {
16
- encodeMessageNode,
17
- decodeMessageNode,
18
- generateMessageId,
19
- generateStanzaId
20
- } from './message-encoder.js';
21
- import { encodeBinaryNode, BinaryNode } from '../core/binary.js';
22
- import { jidToString, isGroupJid } from '../utils/jid.js';
23
- import { SilentLogger } from '../utils/logger.js';
24
-
25
- // ============== Send Message Result Tracking ==============
26
-
27
- interface PendingMessage {
28
- jid: string;
29
- messageId: string;
30
- resolve: (result: SendMessageResult) => void;
31
- reject: (err: Error) => void;
32
- timeout: NodeJS.Timeout;
33
- }
34
-
35
- /**
36
- * Track pending message sends untuk kaitin response dengan server ACK
37
- */
38
- export class PendingMessageTracker {
39
- private pending: Map<string, PendingMessage> = new Map();
40
-
41
- add(jid: string, messageId: string, resolve: (r: SendMessageResult) => void, reject: (e: Error) => void, timeoutMs: number = 30000): void {
42
- const timeout = setTimeout(() => {
43
- this.pending.delete(messageId);
44
- reject(new Error(`Message send timeout for ${messageId}`));
45
- }, timeoutMs);
46
-
47
- this.pending.set(messageId, { jid, messageId, resolve, reject, timeout });
48
- }
49
-
50
- resolve(messageId: string, result: SendMessageResult): void {
51
- const p = this.pending.get(messageId);
52
- if (p) {
53
- clearTimeout(p.timeout);
54
- this.pending.delete(messageId);
55
- p.resolve(result);
56
- }
57
- }
58
-
59
- reject(messageId: string, err: Error): void {
60
- const p = this.pending.get(messageId);
61
- if (p) {
62
- clearTimeout(p.timeout);
63
- this.pending.delete(messageId);
64
- p.reject(err);
65
- }
66
- }
67
-
68
- /** Clear all pending (untuk disconnect) */
69
- rejectAll(err: Error): void {
70
- for (const [, p] of this.pending) {
71
- clearTimeout(p.timeout);
72
- p.reject(err);
73
- }
74
- this.pending.clear();
75
- }
76
-
77
- size(): number {
78
- return this.pending.size;
79
- }
80
- }
81
-
82
- // ============== Message Sender ==============
83
-
84
- export interface MessageSenderOptions {
85
- /** Function untuk kirim raw bytes via WebSocket */
86
- send: (data: Uint8Array) => void;
87
- /** Logger */
88
- logger?: WALogger;
89
- /** Track pending sends */
90
- tracker?: PendingMessageTracker;
91
- }
92
-
93
- export class MessageSender {
94
- private send: (data: Uint8Array) => void;
95
- private logger: WALogger;
96
- private tracker: PendingMessageTracker;
97
-
98
- constructor(opts: MessageSenderOptions) {
99
- this.send = opts.send;
100
- this.logger = opts.logger ?? new SilentLogger();
101
- this.tracker = opts.tracker ?? new PendingMessageTracker();
102
- }
103
-
104
- /**
105
- * Send message ke recipient
106
- */
107
- async sendMessage(
108
- jid: JIDLike,
109
- content: MessageContent,
110
- options: {
111
- messageId?: string;
112
- participant?: string;
113
- timeoutMs?: number;
114
- } = {}
115
- ): Promise<SendMessageResult> {
116
- const messageId = options.messageId ?? generateMessageId();
117
- const jidStr = jidToString(jid);
118
-
119
- this.logger.debug(`Sending message ${messageId} to ${jidStr}`);
120
-
121
- // Build message node
122
- const messageNode = encodeMessageNode(jid, content, {
123
- messageId,
124
- participant: options.participant
125
- });
126
-
127
- // Wrap dalam <message> envelope
128
- const envelope: BinaryNode = {
129
- tag: 'message',
130
- attrs: {
131
- to: jidStr,
132
- type: 'text',
133
- id: messageId
134
- },
135
- content: [messageNode]
136
- };
137
-
138
- const binaryData = encodeBinaryNode(envelope);
139
-
140
- // Promise yang resolve ketika server ACK
141
- return new Promise<SendMessageResult>((resolve, reject) => {
142
- this.tracker.add(jidStr, messageId, resolve, reject, options.timeoutMs);
143
-
144
- try {
145
- this.send(binaryData);
146
- } catch (err: any) {
147
- this.tracker.reject(messageId, err);
148
- }
149
- });
150
- }
151
-
152
- /**
153
- * Forward message ke recipient lain
154
- */
155
- async forwardMessage(
156
- to: JIDLike,
157
- message: WAMessage,
158
- options: { timeoutMs?: number } = {}
159
- ): Promise<SendMessageResult> {
160
- const messageId = generateMessageId();
161
- const jidStr = jidToString(to);
162
-
163
- this.logger.debug(`Forwarding message ${message.key.id} -> ${jidStr}`);
164
-
165
- // Build forward node: <message to=... type=... id=...>
166
- // dengan contextInfo.forwardingScore dan original message
167
- const forwardNode: BinaryNode = {
168
- tag: 'message',
169
- attrs: {
170
- to: jidStr,
171
- type: 'text',
172
- id: messageId
173
- },
174
- content: [
175
- message.message?.text ? {
176
- tag: 'conversation',
177
- attrs: {},
178
- content: message.message.text
179
- } : null,
180
- {
181
- tag: 'contextInfo',
182
- attrs: {},
183
- content: [
184
- {
185
- tag: 'stanzaId',
186
- attrs: {},
187
- content: message.key.id
188
- },
189
- {
190
- tag: 'participant',
191
- attrs: {},
192
- content: jidToString(message.key.participant ?? message.key.remoteJid)
193
- },
194
- {
195
- tag: 'forwardingScore',
196
- attrs: {},
197
- content: '1'
198
- }
199
- ]
200
- }
201
- ].filter(Boolean) as any[]
202
- };
203
-
204
- const binaryData = encodeBinaryNode(forwardNode);
205
-
206
- return new Promise<SendMessageResult>((resolve, reject) => {
207
- this.tracker.add(jidStr, messageId, resolve, reject, options.timeoutMs);
208
- try {
209
- this.send(binaryData);
210
- } catch (err: any) {
211
- this.tracker.reject(messageId, err);
212
- }
213
- });
214
- }
215
-
216
- /**
217
- * Delete message (revoke)
218
- */
219
- async deleteMessage(
220
- jid: JIDLike,
221
- key: WAMessageKey,
222
- options: { revokeEveryone?: boolean; timeoutMs?: number } = {}
223
- ): Promise<SendMessageResult> {
224
- const messageId = generateMessageId();
225
- const jidStr = jidToString(jid);
226
-
227
- const revokeNode: BinaryNode = {
228
- tag: 'message',
229
- attrs: {
230
- to: jidStr,
231
- type: 'revoke',
232
- id: messageId
233
- },
234
- content: [
235
- {
236
- tag: 'revokeMessage',
237
- attrs: {
238
- id: key.id,
239
- fromMe: key.fromMe ? 'true' : 'false',
240
- participant: jidToString(key.participant ?? key.remoteJid),
241
- type: options.revokeEveryone ? 'everyone' : 'me'
242
- }
243
- }
244
- ]
245
- };
246
-
247
- const binaryData = encodeBinaryNode(revokeNode);
248
-
249
- return new Promise<SendMessageResult>((resolve, reject) => {
250
- this.tracker.add(jidStr, messageId, resolve, reject, options.timeoutMs);
251
- try {
252
- this.send(binaryData);
253
- } catch (err: any) {
254
- this.tracker.reject(messageId, err);
255
- }
256
- });
257
- }
258
-
259
- /**
260
- * React ke message dengan emoji
261
- */
262
- async reactToMessage(
263
- jid: JIDLike,
264
- key: WAMessageKey,
265
- emoji: string,
266
- options: { timeoutMs?: number } = {}
267
- ): Promise<SendMessageResult> {
268
- const messageId = generateMessageId();
269
- const jidStr = jidToString(jid);
270
-
271
- const reactionNode: BinaryNode = {
272
- tag: 'message',
273
- attrs: {
274
- to: jidStr,
275
- type: 'reaction',
276
- id: messageId
277
- },
278
- content: [
279
- {
280
- tag: 'reactionMessage',
281
- attrs: {
282
- key: JSON.stringify({
283
- id: key.id,
284
- fromMe: key.fromMe,
285
- remoteJid: jidToString(key.remoteJid),
286
- participant: key.participant ? jidToString(key.participant) : undefined
287
- }),
288
- text: emoji,
289
- timestamp: Math.floor(Date.now() / 1000).toString()
290
- }
291
- }
292
- ]
293
- };
294
-
295
- const binaryData = encodeBinaryNode(reactionNode);
296
-
297
- return new Promise<SendMessageResult>((resolve, reject) => {
298
- this.tracker.add(jidStr, messageId, resolve, reject, options.timeoutMs);
299
- try {
300
- this.send(binaryData);
301
- } catch (err: any) {
302
- this.tracker.reject(messageId, err);
303
- }
304
- });
305
- }
306
-
307
- /**
308
- * Update tracker ketika ACK diterima
309
- */
310
- handleAck(messageId: string, status: MessageStatus, timestamp?: number): void {
311
- this.tracker.resolve(messageId, {
312
- key: {
313
- remoteJid: '',
314
- fromMe: true,
315
- id: messageId
316
- },
317
- status,
318
- messageTimestamp: timestamp
319
- });
320
- }
321
-
322
- /**
323
- * Reject all pending (untuk disconnect)
324
- */
325
- destroy(): void {
326
- this.tracker.rejectAll(new Error('Connection closed'));
327
- }
328
- }
329
-
330
- // ============== Message Receiver ==============
331
-
332
- export interface MessageReceiverOptions {
333
- logger?: WALogger;
334
- /** Handler untuk incoming messages */
335
- onMessage?: (messages: WAMessage[], type: 'append' | 'notify') => void;
336
- /** Handler untuk status updates */
337
- onStatusUpdate?: (key: WAMessageKey, status: MessageStatus) => void;
338
- }
339
-
340
- export class MessageReceiver {
341
- private logger: WALogger;
342
- private onMessage?: (messages: WAMessage[], type: 'append' | 'notify') => void;
343
- private onStatusUpdate?: (key: WAMessageKey, status: MessageStatus) => void;
344
-
345
- constructor(opts: MessageReceiverOptions) {
346
- this.logger = opts.logger ?? new SilentLogger();
347
- this.onMessage = opts.onMessage;
348
- this.onStatusUpdate = opts.onStatusUpdate;
349
- }
350
-
351
- /**
352
- * Handle incoming binary node (dari WebSocket)
353
- */
354
- handleNode(node: BinaryNode): void {
355
- if (!node) return;
356
-
357
- switch (node.tag) {
358
- case 'message':
359
- this.handleMessageNode(node);
360
- break;
361
- case 'receipt':
362
- this.handleReceiptNode(node);
363
- break;
364
- case 'status':
365
- this.handleStatusNode(node);
366
- break;
367
- case 'ack':
368
- this.handleAckNode(node);
369
- break;
370
- default:
371
- // Unknown node type
372
- this.logger.trace(`Unhandled node: ${node.tag}`);
373
- }
374
- }
375
-
376
- private handleMessageNode(node: BinaryNode): void {
377
- if (!this.onMessage) return;
378
-
379
- const attrs = node.attrs || {};
380
- const from = attrs.from ?? '';
381
- const fromMe = attrs.fromMe === 'true' || attrs.type === 'send';
382
- const id = attrs.id;
383
- const type = attrs.type;
384
-
385
- // Convert ke WAMessage
386
- const message = decodeMessageNode(node, fromMe);
387
- if (!message) return;
388
-
389
- this.logger.debug(`Received message ${id} from ${from} (type: ${type})`);
390
-
391
- this.onMessage([message], type === 'append' ? 'append' : 'notify');
392
- }
393
-
394
- private handleReceiptNode(node: BinaryNode): void {
395
- const attrs = node.attrs || {};
396
- const id = attrs.id;
397
- const type = attrs.type;
398
- const from = attrs.from;
399
-
400
- if (!this.onStatusUpdate || !id) return;
401
-
402
- const statusMap: Record<string, MessageStatus> = {
403
- 'read': 'read',
404
- 'delivered': 'delivered',
405
- 'played': 'played'
406
- };
407
-
408
- const status = statusMap[type];
409
- if (status) {
410
- this.onStatusUpdate({
411
- remoteJid: from,
412
- fromMe: true,
413
- id
414
- }, status);
415
- }
416
- }
417
-
418
- private handleStatusNode(node: BinaryNode): void {
419
- const attrs = node.attrs || {};
420
- const id = attrs.id;
421
- const type = attrs.type;
422
- const from = attrs.from;
423
-
424
- if (!this.onStatusUpdate || !id) return;
425
-
426
- const statusMap: Record<string, MessageStatus> = {
427
- 'read': 'read',
428
- 'delivered': 'delivered',
429
- 'played': 'played'
430
- };
431
-
432
- const status = statusMap[type];
433
- if (status) {
434
- this.onStatusUpdate({
435
- remoteJid: from,
436
- fromMe: true,
437
- id
438
- }, status);
439
- }
440
- }
441
-
442
- private handleAckNode(node: BinaryNode): void {
443
- // ACK dari server untuk confirm message received
444
- const attrs = node.attrs || {};
445
- const id = attrs.id;
446
- const type = attrs.type;
447
-
448
- if (!id) return;
449
-
450
- const statusMap: Record<string, MessageStatus> = {
451
- 'received': 'sent',
452
- 'read': 'read',
453
- 'played': 'played'
454
- };
455
-
456
- const status = statusMap[type] ?? 'sent';
457
- if (this.onStatusUpdate) {
458
- this.onStatusUpdate({
459
- remoteJid: '',
460
- fromMe: true,
461
- id
462
- }, status);
463
- }
464
- }
465
-
466
- /**
467
- * Set handlers (untuk runtime binding)
468
- */
469
- setHandlers(opts: MessageReceiverOptions): void {
470
- this.onMessage = opts.onMessage;
471
- this.onStatusUpdate = opts.onStatusUpdate;
472
- }
473
- }
474
-
475
- // ============== Read Receipt Sender ==============
476
-
477
- /**
478
- * Send read receipts untuk incoming messages
479
- */
480
- export function buildReadReceiptNode(
481
- jid: JIDLike,
482
- messageIds: string[],
483
- participant?: JIDLike
484
- ): BinaryNode {
485
- const attrs: any = {
486
- to: jidToString(jid),
487
- type: 'read',
488
- id: messageIds[0]
489
- };
490
- if (participant) attrs.participant = jidToString(participant);
491
-
492
- return {
493
- tag: 'receipt',
494
- attrs,
495
- content: messageIds.map(id => ({
496
- tag: 'receipt',
497
- attrs: { id, t: Math.floor(Date.now() / 1000).toString() }
498
- }))
499
- };
500
- }
501
-
502
- /**
503
- * Send typing indicator
504
- */
505
- export function buildChatPresenceNode(
506
- jid: JIDLike,
507
- type: 'composing' | 'paused' | 'recording',
508
- media?: 'audio' | 'video'
509
- ): BinaryNode {
510
- return {
511
- tag: 'chat',
512
- attrs: {
513
- to: jidToString(jid),
514
- type
515
- },
516
- content: media ? [{
517
- tag: media,
518
- attrs: {}
519
- }] : undefined
520
- };
521
- }