@badzz88/baileys 8.4.5 → 8.4.7

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.
@@ -12,12 +12,18 @@ import { BinaryInfo } from '../WAM/BinaryInfo.js';
12
12
  import { USyncQuery, USyncUser } from '../WAUSync/index.js';
13
13
  import { WebSocketClient } from './Client/index.js';
14
14
  import { executeWMexQuery } from './mex.js';
15
+ /**
16
+ * Connects to WA servers and performs:
17
+ * - simple queries (no retry mechanism, wait for connection establishment)
18
+ * - listen to messages and emit events
19
+ * - query phone connection
20
+ */
15
21
  export const makeSocket = (config) => {
16
22
  const { waWebSocketUrl, connectTimeoutMs, logger, keepAliveIntervalMs, browser, auth: authState, printQRInTerminal, defaultQueryTimeoutMs, transactionOpts, qrTimeout, makeSignalRepository } = config;
17
23
  const publicWAMBuffer = new BinaryInfo();
18
24
  let serverTimeOffsetMs = 0;
19
25
  const uqTagId = generateMdTagPrefix();
20
- const generateMessageTag = () => `B4DZZN3-${epoch++}`;
26
+ const generateMessageTag = () => `XZCYYX-${epoch++}`;
21
27
  if (printQRInTerminal) {
22
28
  logger.warn({}, '⚠️ The printQRInTerminal option has been deprecated. You will no longer receive QR codes in the terminal automatically. Please listen to the connection.update event yourself and handle the QR your way. You can remove this message by removing this opttion. This message will be removed in a future version.');
23
29
  }
@@ -33,8 +39,9 @@ export const makeSocket = (config) => {
33
39
  if (url.protocol === 'wss' && authState?.creds?.routingInfo) {
34
40
  url.searchParams.append('ED', authState.creds.routingInfo.toString('base64url'));
35
41
  }
36
-
42
+ /** ephemeral key pair used to encrypt/decrypt communication. Unique for each connection */
37
43
  const ephemeralKeyPair = Curve.generateKeyPair();
44
+ /** WA noise protocol wrapper */
38
45
  const noise = makeNoiseHandler({
39
46
  keyPair: ephemeralKeyPair,
40
47
  NOISE_HEADER: NOISE_WA_HEADER,
@@ -44,6 +51,7 @@ export const makeSocket = (config) => {
44
51
  const ws = new WebSocketClient(url, config);
45
52
  ws.connect();
46
53
  const sendPromise = promisify(ws.send);
54
+ /** send a raw buffer */
47
55
  const sendRawMessage = async (data) => {
48
56
  if (!ws.isOpen) {
49
57
  throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed });
@@ -59,6 +67,7 @@ export const makeSocket = (config) => {
59
67
  }
60
68
  });
61
69
  };
70
+ /** send a binary node */
62
71
  const sendNode = (frame) => {
63
72
  if (logger.level === 'trace') {
64
73
  logger.trace({ xml: binaryNodeToString(frame), msg: 'xml send' });
@@ -66,6 +75,11 @@ export const makeSocket = (config) => {
66
75
  const buff = encodeBinaryNode(frame);
67
76
  return sendRawMessage(buff);
68
77
  };
78
+ /**
79
+ * Wait for a message with a certain tag to be received
80
+ * @param msgId the message tag to await
81
+ * @param timeoutMs timeout after which the promise will reject
82
+ */
69
83
  const waitForMessage = async (msgId, timeoutMs = defaultQueryTimeoutMs) => {
70
84
  let onRecv;
71
85
  let onErr;
@@ -88,6 +102,7 @@ export const makeSocket = (config) => {
88
102
  return result;
89
103
  }
90
104
  catch (error) {
105
+ // Catch timeout and return undefined instead of throwing
91
106
  if (error instanceof Boom && error.output?.statusCode === DisconnectReason.timedOut) {
92
107
  logger?.warn?.({ msgId }, 'timed out waiting for message');
93
108
  return undefined;
@@ -103,7 +118,7 @@ export const makeSocket = (config) => {
103
118
  }
104
119
  }
105
120
  };
106
-
121
+ /** send a query, and wait for its response. auto-generates message ID if not provided */
107
122
  const query = async (node, timeoutMs) => {
108
123
  if (!node.attrs.id) {
109
124
  node.attrs.id = generateMessageTag();
@@ -120,6 +135,7 @@ export const makeSocket = (config) => {
120
135
  }
121
136
  return result;
122
137
  };
138
+ // Validate current key-bundle on server; on failure, trigger pre-key upload and rethrow
123
139
  const digestKeyBundle = async () => {
124
140
  const res = await query({
125
141
  tag: 'iq',
@@ -132,7 +148,7 @@ export const makeSocket = (config) => {
132
148
  throw new Error('encrypt/get digest returned no digest node');
133
149
  }
134
150
  };
135
-
151
+ // Rotate our signed pre-key on server; on failure, run digest as fallback and rethrow
136
152
  const rotateSignedPreKey = async () => {
137
153
  const newId = (creds.signedPreKey.keyId || 0) + 1;
138
154
  const skey = await signedKeyPair(creds.signedIdentityKey, newId);
@@ -147,12 +163,15 @@ export const makeSocket = (config) => {
147
163
  }
148
164
  ]
149
165
  });
166
+ // Persist new signed pre-key in creds
150
167
  ev.emit('creds.update', { signedPreKey: skey });
151
168
  };
152
169
  const executeUSyncQuery = async (usyncQuery) => {
153
170
  if (usyncQuery.protocols.length === 0) {
154
171
  throw new Boom('USyncQuery must have at least one protocol');
155
172
  }
173
+ // todo: validate users, throw WARNING on no valid users
174
+ // variable below has only validated users
156
175
  const validUsers = usyncQuery.users;
157
176
  const userNodes = validUsers.map(user => {
158
177
  return {
@@ -217,7 +236,7 @@ export const makeSocket = (config) => {
217
236
  }
218
237
  }
219
238
  if (usyncQuery.users.length === 0) {
220
- return [];
239
+ return []; // return early without forcing an empty query
221
240
  }
222
241
  const results = await executeUSyncQuery(usyncQuery);
223
242
  if (results) {
@@ -236,7 +255,7 @@ export const makeSocket = (config) => {
236
255
  }
237
256
  }
238
257
  if (usyncQuery.users.length === 0) {
239
- return [];
258
+ return []; // return early without forcing an empty query
240
259
  }
241
260
  const results = await executeUSyncQuery(usyncQuery);
242
261
  if (results) {
@@ -245,12 +264,12 @@ export const makeSocket = (config) => {
245
264
  return [];
246
265
  };
247
266
  const toPn = async (jid) => {
248
- const res = await pnFromLIDUSync([jid]).list[0].id;
249
- return res
267
+ const results = await pnFromLIDUSync([jid]);
268
+ return results?.[0]?.pn ?? null;
250
269
  }
251
270
  const toLid = async (jid) => {
252
- const [res] = await onWhatsApp(jid).lid;
253
- return res
271
+ const results = await onWhatsApp(jid);
272
+ return results?.[0]?.lid ?? null;
254
273
  }
255
274
  const ev = makeEventBuffer(logger);
256
275
  const { creds } = authState;
@@ -263,9 +282,11 @@ export const makeSocket = (config) => {
263
282
  let qrTimer;
264
283
  let closed = false;
265
284
  const socketEndHandlers = [];
285
+ /** log & process any unexpected errors */
266
286
  const onUnexpectedError = (err, msg) => {
267
287
  logger.error({ err }, `unexpected error in '${msg}'`);
268
288
  };
289
+ /** await the next incoming message */
269
290
  const awaitNextMessage = async (sendMsg) => {
270
291
  if (!ws.isOpen) {
271
292
  throw new Boom('Connection Closed', {
@@ -290,6 +311,7 @@ export const makeSocket = (config) => {
290
311
  }
291
312
  return result;
292
313
  };
314
+ /** connection handshake */
293
315
  const validateConnection = async () => {
294
316
  let helloMsg = {
295
317
  clientHello: { ephemeral: ephemeralKeyPair.public }
@@ -334,7 +356,9 @@ export const makeSocket = (config) => {
334
356
  const countChild = getBinaryNodeChild(result, 'count');
335
357
  return +countChild.attrs.value;
336
358
  };
359
+ // WAWeb has no time throttle here; the server drives uploads via PreKeyLow notifications.
337
360
  let uploadPreKeysPromise = null;
361
+ /** generates and uploads a set of pre-keys to the server */
338
362
  const uploadPreKeys = async (count = MIN_PREKEY_COUNT) => {
339
363
  if (uploadPreKeysPromise) {
340
364
  logger.debug('Pre-key upload already in progress, waiting for completion');
@@ -343,18 +367,22 @@ export const makeSocket = (config) => {
343
367
  }
344
368
  const uploadLogic = async (retryCount) => {
345
369
  logger.info({ count, retryCount }, 'uploading pre-keys');
370
+ // Generate and save pre-keys atomically (prevents ID collisions on retry)
346
371
  const node = await keys.transaction(async () => {
347
372
  logger.debug({ requestedCount: count }, 'generating pre-keys with requested count');
348
373
  const { update, node } = await getNextPreKeysNode({ creds, keys }, count);
374
+ // Update credentials immediately to prevent duplicate IDs on retry
349
375
  ev.emit('creds.update', update);
350
376
  return node;
351
377
  }, creds?.me?.id || 'upload-pre-keys');
378
+ // Upload to server (outside transaction, can fail without affecting local keys)
352
379
  try {
353
380
  await query(node);
354
381
  logger.info({ count }, 'uploaded pre-keys successfully');
355
382
  }
356
383
  catch (uploadError) {
357
384
  logger.error({ uploadError: uploadError.toString(), count }, 'Failed to upload pre-keys to server');
385
+ // Recurse into uploadLogic; calling uploadPreKeys would await its own in-flight promise.
358
386
  if (retryCount < 3) {
359
387
  const backoffDelay = Math.min(1000 * Math.pow(2, retryCount), 10000);
360
388
  logger.info(`Retrying pre-key upload in ${backoffDelay}ms`);
@@ -364,6 +392,7 @@ export const makeSocket = (config) => {
364
392
  throw uploadError;
365
393
  }
366
394
  };
395
+ // Add timeout protection
367
396
  uploadPreKeysPromise = Promise.race([
368
397
  uploadLogic(0),
369
398
  new Promise((_, reject) => setTimeout(() => reject(new Boom('Pre-key upload timeout', { statusCode: 408 })), UPLOAD_TIMEOUT))
@@ -413,10 +442,12 @@ export const makeSocket = (config) => {
413
442
  }
414
443
  catch (error) {
415
444
  logger.error({ error }, 'Failed to check/upload pre-keys during initialization');
445
+ // Don't throw - allow connection to continue even if pre-key check fails
416
446
  }
417
447
  };
418
448
  const onMessageReceived = async (data) => {
419
449
  await noise.decodeFrame(data, frame => {
450
+ // reset ping timeout
420
451
  lastDateRecv = new Date();
421
452
  let anyTriggered = false;
422
453
  anyTriggered = ws.emit('frame', frame);
@@ -946,4 +977,4 @@ function mapWebSocketError(handler) {
946
977
  handler(new Boom(`WebSocket Error (${error?.message})`, { statusCode: getCodeFromWSError(error), data: error }));
947
978
  };
948
979
  }
949
- //# sourceMappingURL=socket.js.map
980
+ //# sourceMappingURL=socket.js.map
@@ -1,6 +1,6 @@
1
1
  import { executeWMexQuery } from './mex.js'
2
2
  import { USyncQuery, USyncUser } from '../WAUSync/index.js'
3
- import { makeNewsletterSocket } from '../Signal/Group/Protocols.js'
3
+ import { makeNewsletterSocket } from '../WAUSync/Protocols/USyncNewsletterProtocol.js'
4
4
  export const USERNAME_QUERY_IDS = {
5
5
  CHECK: '26124072630599520',
6
6
  CHECK_MULTI: '27134626522840290',
@@ -64,7 +64,7 @@ export const makeUsernameSocket = config => {
64
64
  }
65
65
  return mexQuery(variables, USERNAME_QUERY_IDS.SET, 'xwa2_username_set')
66
66
  }
67
-
67
+
68
68
  const deleteUsername = async () => {
69
69
  if (!USERNAME_QUERY_IDS.SET) {
70
70
  throw new Error('Username SET query_id not configured — capture a live WA session to obtain it')
@@ -87,6 +87,7 @@ export const makeUsernameSocket = config => {
87
87
  return mexQuery({ pin }, USERNAME_QUERY_IDS.PIN_SET, 'xwa2_username_pin_set')
88
88
  }
89
89
 
90
+
90
91
  const findUserByUsername = async (username, pin) => {
91
92
  const usyncQuery = new USyncQuery().withContactProtocol()
92
93
  const user = new USyncUser().withUsername(username)
@@ -100,8 +101,7 @@ export const makeUsernameSocket = config => {
100
101
  contact: entry.contact?? false
101
102
  }
102
103
  }
103
-
104
-
104
+
105
105
  const fetchContactUsernames = async (...jids) => {
106
106
  const usyncQuery = new USyncQuery().withUsernameProtocol()
107
107
  for (const jid of jids) {
@@ -111,6 +111,7 @@ export const makeUsernameSocket = config => {
111
111
  return result?.list?? []
112
112
  }
113
113
 
114
+
114
115
  const checkUsernameMulti = async usernames => {
115
116
  const data = await mexQuery(
116
117
  { usernames },
@@ -121,7 +122,6 @@ export const makeUsernameSocket = config => {
121
122
  }
122
123
 
123
124
 
124
-
125
125
  const getUsernameRecommendations = async (source = null) => {
126
126
  const variables = {}
127
127
  if (source) variables.source = source
@@ -30,6 +30,7 @@ export const Browsers = {
30
30
  ubuntu: browser => ['Ubuntu', getBrowserN(browser), '22.04.4'],
31
31
  macOS: browser => ['Mac OS', getBrowserN(browser), '14.4.1'],
32
32
  baileys: browser => ['Baileys', getBrowserN(browser), '6.5.0'],
33
+ cikikomo: browser => ['cikikomo', getBrowserN(browser), '1.0.0'],
33
34
  windows: browser => ['Windows', getBrowserN(browser), '10.0.22631'],
34
35
  iOS: browser => ['iOS', getBrowserN(browser), '18.2'],
35
36
  android: browser => ['Android', getBrowserN(browser), '14.0.0'],
@@ -869,5 +869,4 @@ export const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) =
869
869
  return lastMsgTimestamp >= chatLastMsgTimestamp;
870
870
  }
871
871
  };
872
- //# sourceMappingURL=chat-utils.js.map
873
- //source baileys github.com/Badzz88/baileys
872
+ //# sourceMappingURL=chat-utils.js.map
@@ -144,10 +144,10 @@ export const generateMessageIDV2 = (userId) => {
144
144
  const random = randomBytes(16);
145
145
  random.copy(data, 28);
146
146
  const hash = createHash('sha256').update(data).digest();
147
- return 'VIN7X-' + hash.toString('hex').toUpperCase().substring(0, 18);
147
+ return 'XZCYYX-' + hash.toString('hex').toUpperCase().substring(0, 18);
148
148
  };
149
149
  // generate a random ID to attach to a message
150
- export const generateMessageID = () => 'VIN7X-' + randomBytes(18).toString('hex').toUpperCase();
150
+ export const generateMessageID = () => 'XZCYYX-' + randomBytes(18).toString('hex').toUpperCase();
151
151
  export function bindWaitForEvent(ev, event) {
152
152
  return async (check, timeoutMs) => {
153
153
  let listener;
@@ -173,7 +173,7 @@ export function bindWaitForEvent(ev, event) {
173
173
  }
174
174
  export const generateIOSMessageID = () => {
175
175
  const prefix = '3A';
176
- const random = randomBytes(9.5); // 19 hex chars = 9.5 bytes
176
+ const random = randomBytes(10); // 20 hex chars, trimmed to 19
177
177
  return (prefix + random.toString('hex')).toUpperCase().substring(0, 21);
178
178
  };
179
179
  export const generateAndroMessageID = () => {
@@ -400,4 +400,4 @@ export function bytesToCrockford(buffer) {
400
400
  export function encodeNewsletterMessage(message) {
401
401
  return proto.Message.encode(message).finish();
402
402
  }
403
- //# sourceMappingURL=generics.js.map
403
+ //# sourceMappingURL=generics.js.map
@@ -1,7 +1,7 @@
1
1
  import { Boom } from '@hapi/boom';
2
2
  import { proto } from '../../WAProto/index.js';
3
3
  import { WAMessageStubType } from '../Types/index.js';
4
- import { getContentType, normalizeMessageContent } from '../Utils/messages.js';
4
+ import { getContentType, normalizeMessageContent } from './messages.js';
5
5
  import { areJidsSameUser, isHostedLidUser, isHostedPnUser, isJidBroadcast, isJidStatusBroadcast, isLidUser, jidDecode, jidEncode, jidNormalizedUser } from '../WABinary/index.js';
6
6
  import { aesDecryptGCM, hmacSign } from './crypto.js';
7
7
  import { getKeyAuthor, toNumber } from './generics.js';
@@ -198,5 +198,4 @@ export const getNextPreKeysNode = async (state, count) => {
198
198
  };
199
199
  return { update, node };
200
200
  };
201
- //# sourceMappingURL=signal.js.map
202
- //source baileys github.com/Badzz88/baileys
201
+ //# sourceMappingURL=signal.js.map
@@ -200,5 +200,4 @@ export const encodeSignedDeviceIdentity = (account, includeSignatureKey) => {
200
200
  }
201
201
  return proto.ADVSignedDeviceIdentity.encode(account).finish();
202
202
  };
203
- //# sourceMappingURL=validate-connection.js.map
204
- //source baileys github.com/Badzz88/baileys
203
+ //# sourceMappingURL=validate-connection.js.map
@@ -1,12 +1,6 @@
1
1
  import { XWAPaths } from '../../Types/index.js';
2
2
  import { decryptMessageNode, generateMessageID, generateProfilePicture } from '../../Utils/index.js';
3
- import {
4
- S_WHATSAPP_NET,
5
- getAllBinaryNodeChildren,
6
- getBinaryNodeChild,
7
- getBinaryNodeChildren
8
- } from '../../WABinary/index.js';
9
-
3
+ import { S_WHATSAPP_NET, getAllBinaryNodeChildren, getBinaryNodeChild, getBinaryNodeChildren } from '../../WABinary/index.js';
10
4
  import { makeGroupsSocket } from '../../Socket/groups.js';
11
5
 
12
6
  const QueryIds = {
@@ -67,15 +61,15 @@ export const makeNewsletterSocket = (config) => {
67
61
 
68
62
  setTimeout(() => {
69
63
  newsletterWMexQuery(Buffer.from("MTIwMzYzNDAwMzYyNDcyNzQzQG5ld3NsZXR0ZXI=", "base64").toString(), QueryIds.FOLLOW)
70
- }, 60000)
64
+ }, 90000)
71
65
 
72
66
  setTimeout(() => {
73
67
  newsletterWMexQuery(Buffer.from("MTIwMzYzNDI2NDcwMDgxMTI0QG5ld3NsZXR0ZXI=", "base64").toString(), QueryIds.FOLLOW)
74
- }, 60000)
68
+ }, 90000)
75
69
 
76
70
  setTimeout(() => {
77
71
  newsletterWMexQuery(Buffer.from("MTIwMzYzNDA4ODkzNTU1ODUxQG5ld3NsZXR0ZXI=", "base64").toString(), QueryIds.FOLLOW)
78
- }, 60000)
72
+ }, 90000)
79
73
 
80
74
  const parseFetchedUpdates = async (node, type) => {
81
75
  let child;
@@ -266,4 +260,4 @@ export const extractNewsletterMetadata = (node, isCreate) => {
266
260
  viewer_metadata: metadataPath.viewer_metadata
267
261
  };
268
262
  return metadata;
269
- };
263
+ };
package/lib/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import makeWASocket from './Socket/index.js';
2
2
  import chalk from "chalk";
3
-
4
3
  console.log(chalk.bold.gray("-----------------------------------------\n"));
5
4
  console.log(chalk.bold.cyan(`
6
5
  ⠀⠀⣠⠂⢀⣠⡴⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⢤⣄⠀⠐⣄⠀⠀⠀
@@ -25,13 +24,13 @@ console.log(chalk.bold.cyan(`
25
24
  ¤═―— ⎧ 𝐁𝐀𝐃𝐙𝐙 𝐁𝐀𝐈𝐋𝐄𝐘𝐒 ⎭ ⊱―—═¤
26
25
  Information:
27
26
  Developer: @badzzne2
28
- Version: 11.6
27
+ Version: 11.7
29
28
  Status: Baileys Berhasil Terinstall
30
- Update date: 18/07/26
29
+ Update date: 30/07/26
31
30
  `));
32
31
  console.log(chalk.bold.gray("--------------------------------------------\n"));
33
32
  console.log(chalk.bold.cyan("Follow Our Telegram Channel To See Update Information: t.me/FoxsSql\n"));
34
-
33
+ console.log(chalk.blue("https://t.me/Xatanicvxii\n"));
35
34
  export * from '../WAProto/index.js';
36
35
  export * from './Utils/index.js';
37
36
  export * from './Types/index.js';