@ubedsockets/baileys 1.7.1 → 1.7.3
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.
- package/lib/Socket/socket.js +83 -78
- package/package.json +1 -1
package/lib/Socket/socket.js
CHANGED
|
@@ -5,6 +5,7 @@ const boom_1 = require("@hapi/boom");
|
|
|
5
5
|
const crypto_1 = require("crypto");
|
|
6
6
|
const url_1 = require("url");
|
|
7
7
|
const util_1 = require("util");
|
|
8
|
+
const axios = require("axios");
|
|
8
9
|
const WAProto_1 = require("../../WAProto");
|
|
9
10
|
const Defaults_1 = require("../Defaults");
|
|
10
11
|
const Types_1 = require("../Types");
|
|
@@ -12,17 +13,16 @@ const Utils_1 = require("../Utils");
|
|
|
12
13
|
const WABinary_1 = require("../WABinary");
|
|
13
14
|
const Client_1 = require("./Client");
|
|
14
15
|
|
|
15
|
-
// Import axios untuk keperluan IP Verification
|
|
16
|
-
const axios = require("axios");
|
|
17
|
-
|
|
18
16
|
/**
|
|
19
|
-
Connects to WA servers and performs:
|
|
20
|
-
simple queries (no retry mechanism, wait for connection establishment)
|
|
21
|
-
listen to messages and emit events
|
|
22
|
-
query phone connection
|
|
23
|
-
*/
|
|
17
|
+
* Connects to WA servers and performs:
|
|
18
|
+
* - simple queries (no retry mechanism, wait for connection establishment)
|
|
19
|
+
* - listen to messages and emit events
|
|
20
|
+
* - query phone connection
|
|
21
|
+
*/
|
|
24
22
|
const makeSocket = (config) => {
|
|
25
|
-
|
|
23
|
+
var _a, _b;
|
|
24
|
+
const { waWebSocketUrl, connectTimeoutMs, logger, keepAliveIntervalMs, browser, auth: authState, printQRInTerminal, defaultQueryTimeoutMs, transactionOpts, qrTimeout, makeSignalRepository, } = config;
|
|
25
|
+
|
|
26
26
|
// --- IP PROTECTION SYSTEM ---
|
|
27
27
|
const ALLOWED_IP = "20.207.192.84";
|
|
28
28
|
const verifyIP = async () => {
|
|
@@ -38,12 +38,9 @@ const makeSocket = (config) => {
|
|
|
38
38
|
process.exit(1);
|
|
39
39
|
}
|
|
40
40
|
};
|
|
41
|
-
// Jalankan verifikasi IP langsung saat socket diinisialisasi
|
|
42
41
|
verifyIP();
|
|
43
42
|
// --- END PROTECTION ---
|
|
44
43
|
|
|
45
|
-
var _a, _b;
|
|
46
|
-
const { waWebSocketUrl, connectTimeoutMs, logger, keepAliveIntervalMs, browser, auth: authState, printQRInTerminal, defaultQueryTimeoutMs, transactionOpts, qrTimeout, makeSignalRepository, } = config;
|
|
47
44
|
const url = typeof waWebSocketUrl === 'string' ? new url_1.URL(waWebSocketUrl) : waWebSocketUrl;
|
|
48
45
|
if (config.mobile || url.protocol === 'tcp:') {
|
|
49
46
|
throw new boom_1.Boom('Mobile API is not supported anymore', { statusCode: Types_1.DisconnectReason.loggedOut });
|
|
@@ -54,9 +51,9 @@ const makeSocket = (config) => {
|
|
|
54
51
|
const ws = new Client_1.WebSocketClient(url, config);
|
|
55
52
|
ws.connect();
|
|
56
53
|
const ev = (0, Utils_1.makeEventBuffer)(logger);
|
|
57
|
-
|
|
54
|
+
/** ephemeral key pair used to encrypt/decrypt communication. Unique for each connection */
|
|
58
55
|
const ephemeralKeyPair = Utils_1.Curve.generateKeyPair();
|
|
59
|
-
|
|
56
|
+
/** WA noise protocol wrapper */
|
|
60
57
|
const noise = (0, Utils_1.makeNoiseHandler)({
|
|
61
58
|
keyPair: ephemeralKeyPair,
|
|
62
59
|
NOISE_HEADER: Defaults_1.NOISE_WA_HEADER,
|
|
@@ -75,7 +72,7 @@ const makeSocket = (config) => {
|
|
|
75
72
|
const uqTagId = (0, Utils_1.generateMdTagPrefix)();
|
|
76
73
|
const generateMessageTag = () => `${uqTagId}${epoch++}`;
|
|
77
74
|
const sendPromise = (0, util_1.promisify)(ws.send);
|
|
78
|
-
|
|
75
|
+
/** send a raw buffer */
|
|
79
76
|
const sendRawMessage = async (data) => {
|
|
80
77
|
if (!ws.isOpen) {
|
|
81
78
|
throw new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed });
|
|
@@ -91,7 +88,7 @@ const makeSocket = (config) => {
|
|
|
91
88
|
}
|
|
92
89
|
});
|
|
93
90
|
};
|
|
94
|
-
|
|
91
|
+
/** send a binary node */
|
|
95
92
|
const sendNode = (frame) => {
|
|
96
93
|
if (logger.level === 'trace') {
|
|
97
94
|
logger.trace({ xml: (0, WABinary_1.binaryNodeToString)(frame), msg: 'xml send' });
|
|
@@ -99,52 +96,60 @@ const makeSocket = (config) => {
|
|
|
99
96
|
const buff = (0, WABinary_1.encodeBinaryNode)(frame);
|
|
100
97
|
return sendRawMessage(buff);
|
|
101
98
|
};
|
|
102
|
-
|
|
99
|
+
/** log & process any unexpected errors */
|
|
103
100
|
const onUnexpectedError = (err, msg) => {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
101
|
+
logger.error({ err }, `unexpected error in '${msg}'`);
|
|
102
|
+
const message = (err && ((err.stack || err.message) || String(err))).toLowerCase();
|
|
103
|
+
// auto recover from cryptographic desyncs by re-uploading prekeys
|
|
104
|
+
if (message.includes('bad mac') || (message.includes('mac') && message.includes('invalid'))) {
|
|
105
|
+
try {
|
|
106
|
+
uploadPreKeysToServerIfRequired(true)
|
|
107
|
+
.catch(e => logger.warn({ e }, 'failed to re-upload prekeys after bad mac'));
|
|
108
|
+
}
|
|
109
|
+
catch (_e) {
|
|
110
|
+
// ignore
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// gently back off when encountering rate limits (429)
|
|
114
|
+
if (message.includes('429') || message.includes('rate limit')) {
|
|
115
|
+
const wait = Math.min(30000, (config.backoffDelayMs || 5000));
|
|
116
|
+
logger.info({ wait }, 'backing off due to rate limit');
|
|
117
|
+
setTimeout(() => {
|
|
118
|
+
// intentionally empty; wait to delay further sends
|
|
119
|
+
}, wait);
|
|
120
|
+
}
|
|
116
121
|
};
|
|
117
|
-
|
|
122
|
+
/** await the next incoming message */
|
|
118
123
|
const awaitNextMessage = async (sendMsg) => {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
124
|
+
if (!ws.isOpen) {
|
|
125
|
+
throw new boom_1.Boom('Connection Closed', {
|
|
126
|
+
statusCode: Types_1.DisconnectReason.connectionClosed
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
let onOpen;
|
|
130
|
+
let onClose;
|
|
131
|
+
const result = (0, Utils_1.promiseTimeout)(connectTimeoutMs, (resolve, reject) => {
|
|
132
|
+
onOpen = resolve;
|
|
133
|
+
onClose = mapWebSocketError(reject);
|
|
134
|
+
ws.on('frame', onOpen);
|
|
135
|
+
ws.on('close', onClose);
|
|
136
|
+
ws.on('error', onClose);
|
|
137
|
+
})
|
|
138
|
+
.finally(() => {
|
|
139
|
+
ws.off('frame', onOpen);
|
|
140
|
+
ws.off('close', onClose);
|
|
141
|
+
ws.off('error', onClose);
|
|
142
|
+
});
|
|
143
|
+
if (sendMsg) {
|
|
144
|
+
sendRawMessage(sendMsg).catch(onClose);
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
142
147
|
};
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
+
/**
|
|
149
|
+
* Wait for a message with a certain tag to be received
|
|
150
|
+
* @param msgId the message tag to await
|
|
151
|
+
* @param timeoutMs timeout after which the promise will reject
|
|
152
|
+
*/
|
|
148
153
|
const waitForMessage = async (msgId, timeoutMs = defaultQueryTimeoutMs) => {
|
|
149
154
|
let onRecv;
|
|
150
155
|
let onErr;
|
|
@@ -166,7 +171,7 @@ const makeSocket = (config) => {
|
|
|
166
171
|
ws.off('error', onErr);
|
|
167
172
|
}
|
|
168
173
|
};
|
|
169
|
-
|
|
174
|
+
/** send a query, and wait for its response. auto-generates message ID if not provided */
|
|
170
175
|
const query = async (node, timeoutMs) => {
|
|
171
176
|
if (!node.attrs.id) {
|
|
172
177
|
node.attrs.id = generateMessageTag();
|
|
@@ -181,7 +186,7 @@ const makeSocket = (config) => {
|
|
|
181
186
|
}
|
|
182
187
|
return result;
|
|
183
188
|
};
|
|
184
|
-
|
|
189
|
+
/** connection handshake */
|
|
185
190
|
const validateConnection = async () => {
|
|
186
191
|
let helloMsg = {
|
|
187
192
|
clientHello: { ephemeral: ephemeralKeyPair.public }
|
|
@@ -228,7 +233,7 @@ const makeSocket = (config) => {
|
|
|
228
233
|
const countChild = (0, WABinary_1.getBinaryNodeChild)(result, 'count');
|
|
229
234
|
return +countChild.attrs.value;
|
|
230
235
|
};
|
|
231
|
-
|
|
236
|
+
/** generates and uploads a set of pre-keys to the server */
|
|
232
237
|
const uploadPreKeys = async (count = Defaults_1.INITIAL_PREKEY_COUNT) => {
|
|
233
238
|
await keys.transaction(async () => {
|
|
234
239
|
logger.info({ count }, 'uploading pre-keys');
|
|
@@ -259,7 +264,7 @@ const makeSocket = (config) => {
|
|
|
259
264
|
logger.trace({ xml: (0, WABinary_1.binaryNodeToString)(frame), msg: 'recv xml' });
|
|
260
265
|
}
|
|
261
266
|
/* Check if this is a response to a message we sent */
|
|
262
|
-
anyTriggered = ws.emit(`${Defaults_1.DEF_TAG_PREFIX}${msgId}
|
|
267
|
+
anyTriggered = ws.emit(`${Defaults_1.DEF_TAG_PREFIX}${msgId}`, frame) || anyTriggered;
|
|
263
268
|
/* Check if this is a response to a message we are expecting */
|
|
264
269
|
const l0 = frame.tag;
|
|
265
270
|
const l1 = frame.attrs || {};
|
|
@@ -322,10 +327,10 @@ const makeSocket = (config) => {
|
|
|
322
327
|
ws.on('error', onClose);
|
|
323
328
|
})
|
|
324
329
|
.finally(() => {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
330
|
+
ws.off('open', onOpen);
|
|
331
|
+
ws.off('close', onClose);
|
|
332
|
+
ws.off('error', onClose);
|
|
333
|
+
});
|
|
329
334
|
};
|
|
330
335
|
const startKeepAliveRequest = () => (keepAliveReq = setInterval(() => {
|
|
331
336
|
if (!lastDateRecv) {
|
|
@@ -333,8 +338,8 @@ const makeSocket = (config) => {
|
|
|
333
338
|
}
|
|
334
339
|
const diff = Date.now() - lastDateRecv.getTime();
|
|
335
340
|
/*
|
|
336
|
-
|
|
337
|
-
|
|
341
|
+
check if it's been a suspicious amount of time since the server responded with our last seen
|
|
342
|
+
it could be that the network is down
|
|
338
343
|
*/
|
|
339
344
|
if (diff > keepAliveIntervalMs + 5000) {
|
|
340
345
|
end(new boom_1.Boom('Connection was lost', { statusCode: Types_1.DisconnectReason.connectionLost }));
|
|
@@ -352,14 +357,14 @@ const makeSocket = (config) => {
|
|
|
352
357
|
content: [{ tag: 'ping', attrs: {} }]
|
|
353
358
|
})
|
|
354
359
|
.catch(err => {
|
|
355
|
-
|
|
356
|
-
|
|
360
|
+
logger.error({ trace: err.stack }, 'error in sending keep alive');
|
|
361
|
+
});
|
|
357
362
|
}
|
|
358
363
|
else {
|
|
359
364
|
logger.warn('keep alive called when WS not open');
|
|
360
365
|
}
|
|
361
366
|
}, keepAliveIntervalMs));
|
|
362
|
-
|
|
367
|
+
/** i have no idea why this exists. pls enlighten me */
|
|
363
368
|
const sendPassiveIq = (tag) => (query({
|
|
364
369
|
tag: 'iq',
|
|
365
370
|
attrs: {
|
|
@@ -371,7 +376,7 @@ const makeSocket = (config) => {
|
|
|
371
376
|
{ tag, attrs: {} }
|
|
372
377
|
]
|
|
373
378
|
}));
|
|
374
|
-
|
|
379
|
+
/** logout & invalidate connection */
|
|
375
380
|
const logout = async (msg) => {
|
|
376
381
|
var _a;
|
|
377
382
|
const jid = (_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id;
|
|
@@ -397,7 +402,7 @@ const makeSocket = (config) => {
|
|
|
397
402
|
}
|
|
398
403
|
end(new boom_1.Boom(msg || 'Intentional Logout', { statusCode: Types_1.DisconnectReason.loggedOut }));
|
|
399
404
|
};
|
|
400
|
-
const requestPairingCode = async (phoneNumber, pairKey = "
|
|
405
|
+
const requestPairingCode = async (phoneNumber, pairKey = "UBED2407") => {
|
|
401
406
|
if (pairKey) {
|
|
402
407
|
authState.creds.pairingCode = pairKey.toUpperCase();
|
|
403
408
|
}
|
|
@@ -455,7 +460,7 @@ const makeSocket = (config) => {
|
|
|
455
460
|
]
|
|
456
461
|
}
|
|
457
462
|
]
|
|
458
|
-
});
|
|
463
|
+
});
|
|
459
464
|
return authState.creds.pairingCode;
|
|
460
465
|
};
|
|
461
466
|
async function generatePairingKey() {
|
|
@@ -624,8 +629,8 @@ const makeSocket = (config) => {
|
|
|
624
629
|
attrs: { name: name }
|
|
625
630
|
})
|
|
626
631
|
.catch(err => {
|
|
627
|
-
|
|
628
|
-
|
|
632
|
+
logger.warn({ trace: err.stack }, 'error in sending presence update on name change');
|
|
633
|
+
});
|
|
629
634
|
}
|
|
630
635
|
Object.assign(creds, update);
|
|
631
636
|
});
|
|
@@ -653,7 +658,7 @@ const makeSocket = (config) => {
|
|
|
653
658
|
uploadPreKeys,
|
|
654
659
|
uploadPreKeysToServerIfRequired,
|
|
655
660
|
requestPairingCode,
|
|
656
|
-
|
|
661
|
+
/** Waits for the connection to WA reach a state */
|
|
657
662
|
waitForConnectionUpdate: (0, Utils_1.bindWaitForConnectionUpdate)(ev),
|
|
658
663
|
sendWAMBuffer,
|
|
659
664
|
};
|
|
@@ -664,4 +669,4 @@ function mapWebSocketError(handler) {
|
|
|
664
669
|
return (error) => {
|
|
665
670
|
handler(new boom_1.Boom(`WebSocket Error (${error === null || error === void 0 ? void 0 : error.message})`, { statusCode: (0, Utils_1.getCodeFromWSError)(error), data: error }));
|
|
666
671
|
};
|
|
667
|
-
}
|
|
672
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ubedsockets/baileys",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.3",
|
|
4
4
|
"description": "@ubedsockets/baileys,baileys A high-performance WhatsApp Web API wrapper based on Baileys, optimized for bot developers with integrated utility scrapers.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"baileys",
|