@langitdeveloper/baileys 2.2.2 → 2.2.4
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/messages-send.js +116 -21
- package/lib/Types/index.js +2 -0
- package/lib/Utils/bot-toolkit.js +16 -40
- package/lib/WABinary/generic-utils.js +33 -7
- package/lib/WABinary/jid-utils.js +18 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +9 -1
- package/lib/WAUSync/USyncUser.js +6 -0
- package/package.json +12 -1
|
@@ -14,6 +14,7 @@ const link_preview_1 = require("../Utils/link-preview");
|
|
|
14
14
|
const WABinary_1 = require("../WABinary");
|
|
15
15
|
const newsletter_1 = require("./newsletter");
|
|
16
16
|
const WAUSync_1 = require("../WAUSync");
|
|
17
|
+
const { isTcTokenExpired, shouldSendNewTcToken, resolveTcTokenJid, resolveIssuanceJid, buildMergedTcTokenIndexWrite, storeTcTokensFromIqResult } = require("../Utils/tc-token-utils");
|
|
17
18
|
const kikyy = require('./dugong');
|
|
18
19
|
const makeMessagesSocket = (config) => {
|
|
19
20
|
const {
|
|
@@ -155,7 +156,12 @@ const makeMessagesSocket = (config) => {
|
|
|
155
156
|
for (const jid of toFetch) {
|
|
156
157
|
query.withUser(new WAUSync_1.USyncUser().withId(jid))
|
|
157
158
|
}
|
|
158
|
-
|
|
159
|
+
let result = await executeUSyncQuery(query)
|
|
160
|
+
if (!result) {
|
|
161
|
+
// stability fix: query device kadang gagal transient (timeout/network), coba sekali lagi sebelum nyerah
|
|
162
|
+
logger.debug({ toFetch }, 'usync device query empty, retrying once')
|
|
163
|
+
result = await executeUSyncQuery(query)
|
|
164
|
+
}
|
|
159
165
|
if (result) {
|
|
160
166
|
const extracted = Utils_1.extractDeviceJids(result?.list, authState.creds.me.id, ignoreZeroDevices)
|
|
161
167
|
const deviceMap = {}
|
|
@@ -236,27 +242,36 @@ const makeMessagesSocket = (config) => {
|
|
|
236
242
|
const patched = await patchMessageBeforeSending(message, jids);
|
|
237
243
|
const bytes = (0, Utils_1.encodeWAMessage)(patched);
|
|
238
244
|
let shouldIncludeDeviceIdentity = false;
|
|
239
|
-
const nodes = await Promise.all(jids.map(async (jid) => {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
245
|
+
const nodes = (await Promise.all(jids.map(async (jid) => {
|
|
246
|
+
try {
|
|
247
|
+
const { type, ciphertext } = await signalRepository
|
|
248
|
+
.encryptMessage({ jid, data: bytes });
|
|
249
|
+
if (type === 'pkmsg') {
|
|
250
|
+
shouldIncludeDeviceIdentity = true;
|
|
251
|
+
}
|
|
252
|
+
const node = {
|
|
253
|
+
tag: 'to',
|
|
254
|
+
attrs: { jid },
|
|
255
|
+
content: [{
|
|
256
|
+
tag: 'enc',
|
|
257
|
+
attrs: {
|
|
258
|
+
v: '2',
|
|
259
|
+
type,
|
|
260
|
+
...extraAttrs || {}
|
|
261
|
+
},
|
|
262
|
+
content: ciphertext
|
|
263
|
+
}]
|
|
264
|
+
};
|
|
265
|
+
return node;
|
|
244
266
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
...extraAttrs || {}
|
|
254
|
-
},
|
|
255
|
-
content: ciphertext
|
|
256
|
-
}]
|
|
257
|
-
};
|
|
258
|
-
return node;
|
|
259
|
-
}));
|
|
267
|
+
catch (error) {
|
|
268
|
+
// fix: "SessionError: No sessions" (atau error encrypt lain) buat 1 device jangan
|
|
269
|
+
// sampe nge-reject Promise.all dan bikin proses crash total - skip device ini aja,
|
|
270
|
+
// device lain tetep kekirim normal.
|
|
271
|
+
logger.warn({ jid, trace: error?.stack, err: error?.toString?.() ?? error }, 'failed to encrypt message for device, skipping (no session?)');
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
}))).filter(Boolean);
|
|
260
275
|
return { nodes, shouldIncludeDeviceIdentity };
|
|
261
276
|
};
|
|
262
277
|
const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, cachedGroupMetadata, useCachedGroupMetadata, statusJidList, AI = true }) => {
|
|
@@ -333,6 +348,15 @@ const makeMessagesSocket = (config) => {
|
|
|
333
348
|
const additionalDevices = await getUSyncDevices(participantsList, !!useUserDevicesCache, false)
|
|
334
349
|
devices.push(...additionalDevices)
|
|
335
350
|
}
|
|
351
|
+
// fallback: kalo server ga ngasih addressingMode di group metadata (kadang kosong/null),
|
|
352
|
+
// tebak dari suffix jid participant sendiri drpd langsung default ke pn - lebih akurat pas grup lid-only
|
|
353
|
+
if (groupData && !groupData.addressingMode && groupData.participants?.length) {
|
|
354
|
+
const lidCount = groupData.participants.filter(p => WABinary_1.isLidUser(p.id)).length
|
|
355
|
+
if (lidCount > 0 && lidCount === groupData.participants.length) {
|
|
356
|
+
groupData.addressingMode = 'lid'
|
|
357
|
+
logger.trace({ jid }, 'inferred addressingMode=lid from participant jid suffix (fallback)')
|
|
358
|
+
}
|
|
359
|
+
}
|
|
336
360
|
const patched = await patchMessageBeforeSending(message, devices.map(d => WABinary_1.jidEncode(d.user, isLid ? 'lid' : 's.whatsapp.net', d.device)));
|
|
337
361
|
const bytes = Utils_1.encodeWAMessage(patched);
|
|
338
362
|
const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage({
|
|
@@ -518,8 +542,59 @@ const makeMessagesSocket = (config) => {
|
|
|
518
542
|
if (!didPushAdditional && additionalNodes && additionalNodes.length > 0) {
|
|
519
543
|
stanza.content.push(...additionalNodes);
|
|
520
544
|
}
|
|
545
|
+
// TC (Trusted Contact) token: attach our stored token for this peer (if any
|
|
546
|
+
// and not expired) onto the outgoing stanza - mirrors WA Web's reliability
|
|
547
|
+
// mechanism for 1:1 chats. Ported from official Baileys v7.
|
|
548
|
+
const is1on1Send = isPrivate && !isStatus;
|
|
549
|
+
const getLIDForPN = signalRepository.lidMapping.getLIDForPN.bind(signalRepository.lidMapping);
|
|
550
|
+
let tcTokenJid = jid;
|
|
551
|
+
let existingTokenEntry;
|
|
552
|
+
if (is1on1Send) {
|
|
553
|
+
try {
|
|
554
|
+
tcTokenJid = await resolveTcTokenJid(jid, getLIDForPN);
|
|
555
|
+
const contactTcTokenData = await authState.keys.get('tctoken', [tcTokenJid]);
|
|
556
|
+
existingTokenEntry = contactTcTokenData[tcTokenJid];
|
|
557
|
+
if (existingTokenEntry?.token?.length && !isTcTokenExpired(existingTokenEntry?.timestamp)) {
|
|
558
|
+
stanza.content.push({
|
|
559
|
+
tag: 'tctoken',
|
|
560
|
+
attrs: { t: String(existingTokenEntry.timestamp) },
|
|
561
|
+
content: existingTokenEntry.token
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
catch (err) {
|
|
566
|
+
logger.debug({ err }, 'tctoken attach failed, sending without it');
|
|
567
|
+
}
|
|
568
|
+
}
|
|
521
569
|
logger.debug({ msgId }, `sending message to ${participants.length} devices`);
|
|
522
570
|
await sendNode(stanza);
|
|
571
|
+
// Fire-and-forget: after sending, issue our own token to this contact so
|
|
572
|
+
// future messages from them get the reliability benefit too. Skipped for
|
|
573
|
+
// protocol messages, PSA, and bot/MetaAI contacts (matches WA Web behavior).
|
|
574
|
+
if (is1on1Send) {
|
|
575
|
+
try {
|
|
576
|
+
const isProtocolMsg = !!Types_1.WAProto.Message.fromObject(message)?.protocolMessage;
|
|
577
|
+
const isBotOrPSA = jid === WABinary_1.PSA_WID || WABinary_1.isJidBot(jid) || WABinary_1.isJidMetaAI(jid);
|
|
578
|
+
if (!isProtocolMsg && !isBotOrPSA && shouldSendNewTcToken(existingTokenEntry?.senderTimestamp)) {
|
|
579
|
+
const issueTimestamp = (0, Utils_1.unixTimestampSeconds)();
|
|
580
|
+
const getPNForLID = signalRepository.lidMapping.getPNForLID.bind(signalRepository.lidMapping);
|
|
581
|
+
resolveIssuanceJid(jid, !!sock.serverProps?.lidTrustedTokenIssueToLid, getLIDForPN, getPNForLID)
|
|
582
|
+
.then((issueJid) => sock.issuePrivacyTokens ? sock.issuePrivacyTokens([issueJid], issueTimestamp) : null)
|
|
583
|
+
.then(async (result) => {
|
|
584
|
+
if (!result) {
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
await storeTcTokensFromIqResult({ result, fallbackJid: tcTokenJid, keys: authState.keys, getLIDForPN });
|
|
588
|
+
const indexWrite = await buildMergedTcTokenIndexWrite(authState.keys, [tcTokenJid]);
|
|
589
|
+
await authState.keys.set({ tctoken: indexWrite });
|
|
590
|
+
})
|
|
591
|
+
.catch((err) => logger.debug({ err }, 'tctoken issuance failed'));
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
catch (err) {
|
|
595
|
+
logger.debug({ err }, 'tctoken post-send issuance setup failed');
|
|
596
|
+
}
|
|
597
|
+
}
|
|
523
598
|
});
|
|
524
599
|
message = Types_1.WAProto.Message.fromObject(message)
|
|
525
600
|
const messageJSON = {
|
|
@@ -653,11 +728,31 @@ const makeMessagesSocket = (config) => {
|
|
|
653
728
|
});
|
|
654
729
|
return result;
|
|
655
730
|
}
|
|
731
|
+
/** issues our own TC (Trusted Contact) tokens to the given jids - used internally after sending, also callable directly */
|
|
732
|
+
const issuePrivacyTokens = async (jids, timestamp) => {
|
|
733
|
+
const t = (timestamp !== undefined ? timestamp : (0, Utils_1.unixTimestampSeconds)()).toString();
|
|
734
|
+
const result = await query({
|
|
735
|
+
tag: 'iq',
|
|
736
|
+
attrs: { to: WABinary_1.S_WHATSAPP_NET, type: 'set', xmlns: 'privacy' },
|
|
737
|
+
content: [
|
|
738
|
+
{
|
|
739
|
+
tag: 'tokens',
|
|
740
|
+
attrs: {},
|
|
741
|
+
content: jids.map((jid) => ({
|
|
742
|
+
tag: 'token',
|
|
743
|
+
attrs: { jid: WABinary_1.jidNormalizedUser(jid), t, type: 'trusted_contact' }
|
|
744
|
+
}))
|
|
745
|
+
}
|
|
746
|
+
]
|
|
747
|
+
});
|
|
748
|
+
return result;
|
|
749
|
+
};
|
|
656
750
|
const waUploadToServer = (0, Utils_1.getWAUploadToServer)(config, refreshMediaConn);
|
|
657
751
|
const rahmi = new kikyy(Utils_1, waUploadToServer, relayMessage, config, sock);
|
|
658
752
|
const waitForMsgMediaUpdate = (0, Utils_1.bindWaitForEvent)(ev, 'messages.media-update');
|
|
659
753
|
return {
|
|
660
754
|
...sock,
|
|
755
|
+
issuePrivacyTokens,
|
|
661
756
|
getPrivacyTokens,
|
|
662
757
|
assertSessions,
|
|
663
758
|
relayMessage,
|
package/lib/Types/index.js
CHANGED
|
@@ -40,4 +40,6 @@ var DisconnectReason;
|
|
|
40
40
|
DisconnectReason[DisconnectReason["multideviceMismatch"] = 411] = "multideviceMismatch";
|
|
41
41
|
DisconnectReason[DisconnectReason["forbidden"] = 403] = "forbidden";
|
|
42
42
|
DisconnectReason[DisconnectReason["unavailableService"] = 503] = "unavailableService";
|
|
43
|
+
// akun kena restrict/timelock dari WA (guess, blm 100% kekonfirm formatnya di MD protocol)
|
|
44
|
+
DisconnectReason[DisconnectReason["restrictedAccess"] = 463] = "restrictedAccess";
|
|
43
45
|
})(DisconnectReason = exports.DisconnectReason || (exports.DisconnectReason = {}));
|
package/lib/Utils/bot-toolkit.js
CHANGED
|
@@ -27,6 +27,18 @@ const makeBotToolkit = (conn, logger) => {
|
|
|
27
27
|
const groupMetaCache = new Map(); // jid -> { data, fetchedAt }
|
|
28
28
|
const GROUP_META_TTL_MS = 60 * 1000;
|
|
29
29
|
return {
|
|
30
|
+
/**
|
|
31
|
+
* Releases bot-toolkit's own internal state (poll trackers, group
|
|
32
|
+
* metadata cache, dedup/rate-limit maps). Call this when a session
|
|
33
|
+
* ends/logs out, alongside the socket's own cleanup, so nothing in
|
|
34
|
+
* this toolkit keeps holding memory for a dead connection.
|
|
35
|
+
*/
|
|
36
|
+
destroy() {
|
|
37
|
+
seenMessageIds.clear();
|
|
38
|
+
rateLimitBuckets.clear();
|
|
39
|
+
groupMetaCache.clear();
|
|
40
|
+
pollTallies.clear();
|
|
41
|
+
},
|
|
30
42
|
/**
|
|
31
43
|
* Checks if a user is an admin/superadmin in a group, using the
|
|
32
44
|
* cached metadata getter above so repeated checks (every message in
|
|
@@ -431,49 +443,13 @@ const makeBotToolkit = (conn, logger) => {
|
|
|
431
443
|
return false;
|
|
432
444
|
},
|
|
433
445
|
/**
|
|
446
|
+
* Asks an Anthropic model to help debug an error / snippet against
|
|
447
|
+
* THIS fork's actual Baileys source, so suggestions are grounded in
|
|
448
|
+
* what's really in your codebase instead of generic upstream advice.
|
|
449
|
+
* Wire this up to whatever command prefix you like in your own bot
|
|
434
450
|
* dispatcher (e.g. `.aimahiru`) - this function only does the actual
|
|
435
451
|
* call + prompt shaping, not command parsing.
|
|
436
|
-
*
|
|
437
|
-
* @param input.errorText the error/stack trace the user is hitting
|
|
438
|
-
* @param input.code the snippet of their bot code, if any
|
|
439
452
|
*/
|
|
440
|
-
async aiMahiru({ errorText, code, apiKey, model = 'claude-haiku-4-5-20251001' }) {
|
|
441
|
-
const key = apiKey || process.env.api_key;
|
|
442
|
-
if (!key) {
|
|
443
|
-
throw new Error('aiMahiru: no Anthropic API key provided (pass apiKey or set api_key)');
|
|
444
|
-
}
|
|
445
|
-
const promptParts = [
|
|
446
|
-
'Kamu adalah Mahiru, asisten debug buat fork Baileys bernama mahiru-bails/@langitdeveloper.',
|
|
447
|
-
'Jawab singkat, bahasa Indonesia santai, fokus ke: kemungkinan sebab error, dan baris/fungsi mana yang perlu dicek.',
|
|
448
|
-
'Jangan ngarang nama file/fungsi yang gak disebutkan user.'
|
|
449
|
-
];
|
|
450
|
-
if (errorText) {
|
|
451
|
-
promptParts.push(`Error yang dialami:\n${errorText}`);
|
|
452
|
-
}
|
|
453
|
-
if (code) {
|
|
454
|
-
promptParts.push(`Kode yang dipakai user:\n\`\`\`js\n${code}\n\`\`\``);
|
|
455
|
-
}
|
|
456
|
-
const res = await fetch('https://api.anthropic.com/v1/messages', {
|
|
457
|
-
method: 'POST',
|
|
458
|
-
headers: {
|
|
459
|
-
'content-type': 'application/json',
|
|
460
|
-
'x-api-key': key,
|
|
461
|
-
'anthropic-version': '2023-06-01'
|
|
462
|
-
},
|
|
463
|
-
body: JSON.stringify({
|
|
464
|
-
model,
|
|
465
|
-
max_tokens: 1000,
|
|
466
|
-
messages: [{ role: 'user', content: promptParts.join('\n\n') }]
|
|
467
|
-
})
|
|
468
|
-
});
|
|
469
|
-
if (!res.ok) {
|
|
470
|
-
const text = await res.text().catch(() => '');
|
|
471
|
-
throw new Error(`aiMahiru: Anthropic API error ${res.status}: ${text}`);
|
|
472
|
-
}
|
|
473
|
-
const data = await res.json();
|
|
474
|
-
const textBlock = (data.content || []).find((c) => c.type === 'text');
|
|
475
|
-
return (textBlock === null || textBlock === void 0 ? void 0 : textBlock.text) || '(no response)';
|
|
476
|
-
}
|
|
477
453
|
};
|
|
478
454
|
};
|
|
479
455
|
exports.makeBotToolkit = makeBotToolkit;
|
|
@@ -5,11 +5,38 @@ const boom_1 = require("@hapi/boom");
|
|
|
5
5
|
const WAProto_1 = require("../../WAProto");
|
|
6
6
|
const Utils_1 = require("../Utils")
|
|
7
7
|
// some extra useful utilities
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
// caches children-by-tag lookups per node so repeatedly calling
|
|
9
|
+
// getBinaryNodeChildren/getBinaryNodeChild on the same node (very common when
|
|
10
|
+
// parsing a stanza with multiple helper calls) doesn't re-scan node.content
|
|
11
|
+
// every time. WeakMap means cached entries disappear once the node itself is
|
|
12
|
+
// garbage collected - no manual cleanup needed.
|
|
13
|
+
const childrenByTagCache = new WeakMap();
|
|
14
|
+
const getChildrenByTag = (node) => {
|
|
15
|
+
if (!Array.isArray(node?.content)) {
|
|
16
|
+
return null;
|
|
11
17
|
}
|
|
12
|
-
|
|
18
|
+
let byTag = childrenByTagCache.get(node);
|
|
19
|
+
if (!byTag) {
|
|
20
|
+
byTag = new Map();
|
|
21
|
+
for (const item of node.content) {
|
|
22
|
+
const tag = item?.tag;
|
|
23
|
+
if (!tag) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
let list = byTag.get(tag);
|
|
27
|
+
if (!list) {
|
|
28
|
+
list = [];
|
|
29
|
+
byTag.set(tag, list);
|
|
30
|
+
}
|
|
31
|
+
list.push(item);
|
|
32
|
+
}
|
|
33
|
+
childrenByTagCache.set(node, byTag);
|
|
34
|
+
}
|
|
35
|
+
return byTag;
|
|
36
|
+
};
|
|
37
|
+
const getBinaryNodeChildren = (node, childTag) => {
|
|
38
|
+
const byTag = getChildrenByTag(node);
|
|
39
|
+
return byTag?.get(childTag) || [];
|
|
13
40
|
}
|
|
14
41
|
exports.getBinaryNodeChildren = getBinaryNodeChildren;
|
|
15
42
|
const getAllBinaryNodeChildren = ({ content }) => {
|
|
@@ -20,9 +47,8 @@ const getAllBinaryNodeChildren = ({ content }) => {
|
|
|
20
47
|
}
|
|
21
48
|
exports.getAllBinaryNodeChildren = getAllBinaryNodeChildren;
|
|
22
49
|
const getBinaryNodeChild = (node, childTag) => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
50
|
+
const byTag = getChildrenByTag(node);
|
|
51
|
+
return byTag?.get(childTag)?.[0];
|
|
26
52
|
}
|
|
27
53
|
exports.getBinaryNodeChild = getBinaryNodeChild;
|
|
28
54
|
const getBinaryNodeChildBuffer = (node, childTag) => {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.jidNormalizedUser = exports.isJidNewsLetter = exports.isJidStatusBroadcast = exports.isJidGroup = exports.isJidBroadcast = exports.isLidUser = exports.isJidUser = exports.areJidsSameUser = exports.jidDecode = exports.jidEncode = exports.STORIES_JID = exports.PSA_WID = exports.SERVER_JID = exports.OFFICIAL_BIZ_JID = exports.S_WHATSAPP_NET = void 0;
|
|
4
|
-
exports.isPnUser = exports.isHostedPnUser = exports.isHostedLidUser = exports.WAJIDDomains = exports.getServerFromDomainType = exports.transferDevice = void 0;
|
|
4
|
+
exports.isPnUser = exports.isHostedPnUser = exports.isHostedLidUser = exports.WAJIDDomains = exports.getServerFromDomainType = exports.transferDevice = exports.isJidBot = void 0;
|
|
5
|
+
/** matches WA's official bot phone-number patterns (used to gate TC token issuance away from bots) */
|
|
6
|
+
const botRegexp = /^1313555\d{4}$|^131655500\d{2}$/;
|
|
7
|
+
const isJidBot = (jid) => !!(jid && botRegexp.test(jid.split('@')[0]) && jid.endsWith('@c.us'));
|
|
8
|
+
exports.isJidBot = isJidBot;
|
|
5
9
|
exports.S_WHATSAPP_NET = '@s.whatsapp.net';
|
|
6
10
|
exports.OFFICIAL_BIZ_JID = '16505361212@c.us';
|
|
7
11
|
exports.SERVER_JID = 'server@c.us';
|
|
@@ -94,6 +98,19 @@ exports.isJidStatusBroadcast = isJidStatusBroadcast;
|
|
|
94
98
|
/** is the jid the newsletter */
|
|
95
99
|
const isJidNewsLetter = (jid) => (jid === null || jid === void 0 ? void 0 : jid.endsWith('newsletter'));
|
|
96
100
|
exports.isJidNewsLetter = isJidNewsLetter;
|
|
101
|
+
/**
|
|
102
|
+
* SPECULATIVE - WA Username / BSUID support (rollout mulai Jul 2026, blm masuk ID, blm ada di protokol MD resmi).
|
|
103
|
+
* BSUID format yg kekonfirm sejauh ini (Cloud API): "US.13491208655302741918" -> kode negara + "." + digit panjang.
|
|
104
|
+
* Belum jelas apakah MD protocol bakal pake domain baru (mis. "@username"/"@bsuid") atau tetap "@s.whatsapp.net"
|
|
105
|
+
* dgn field tambahan. Ini cuma placeholder detector, JANGAN dipake buat encode/kirim sampe ada konfirmasi real traffic.
|
|
106
|
+
*/
|
|
107
|
+
const bsuidRegexp = /^[A-Z]{2}\.\d{6,}$/;
|
|
108
|
+
/** cek apakah string berbentuk BSUID (country-code prefixed id), bukan jid biasa */
|
|
109
|
+
const isBsuid = (id) => !!(id && bsuidRegexp.test(id.split('@')[0]));
|
|
110
|
+
exports.isBsuid = isBsuid;
|
|
111
|
+
/** cek apakah jid pake domain "username" (tebakan, blm ada konfirmasi format resmi dari WA MD protocol) */
|
|
112
|
+
const isUsernameJid = (jid) => (jid === null || jid === void 0 ? void 0 : jid.endsWith('@username'));
|
|
113
|
+
exports.isUsernameJid = isUsernameJid;
|
|
97
114
|
const jidNormalizedUser = (jid) => {
|
|
98
115
|
const result = (0, exports.jidDecode)(jid);
|
|
99
116
|
if (!result) {
|
|
@@ -13,7 +13,15 @@ class USyncContactProtocol {
|
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
15
|
getUserElement(user) {
|
|
16
|
-
//
|
|
16
|
+
// kalo query by username, kirim type='username' + content=username (bukan phone)
|
|
17
|
+
// NOTE: speculative, blm ada konfirmasi format node asli dari traffic MD WA yg beneran punya username
|
|
18
|
+
if (user.type === 'username' && user.username) {
|
|
19
|
+
return {
|
|
20
|
+
tag: 'contact',
|
|
21
|
+
attrs: { type: 'username' },
|
|
22
|
+
content: user.username,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
17
25
|
return {
|
|
18
26
|
tag: 'contact',
|
|
19
27
|
attrs: {},
|
package/lib/WAUSync/USyncUser.js
CHANGED
|
@@ -22,5 +22,11 @@ class USyncUser {
|
|
|
22
22
|
this.personaId = personaId;
|
|
23
23
|
return this;
|
|
24
24
|
}
|
|
25
|
+
// speculative - buat query usync by username (fitur WA username, blm live di ID)
|
|
26
|
+
withUsername(username) {
|
|
27
|
+
this.username = username;
|
|
28
|
+
this.type = 'username';
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
25
31
|
}
|
|
26
32
|
exports.USyncUser = USyncUser;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langitdeveloper/baileys",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.4",
|
|
4
4
|
"description": "WhatsApp API Modification By Langit",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"whatsapp",
|
|
@@ -14,6 +14,17 @@
|
|
|
14
14
|
"author": "Adhiraj Singh",
|
|
15
15
|
"main": "lib/index.js",
|
|
16
16
|
"types": "lib/index.d.ts",
|
|
17
|
+
"type": "commonjs",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./lib/index.d.ts",
|
|
21
|
+
"require": "./lib/index.js",
|
|
22
|
+
"import": "./lib/index.js",
|
|
23
|
+
"default": "./lib/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./package.json": "./package.json",
|
|
26
|
+
"./*": "./lib/*"
|
|
27
|
+
},
|
|
17
28
|
"files": [
|
|
18
29
|
"lib/*",
|
|
19
30
|
"WAProto/*.js",
|