@prototypevip/baileys 0.0.1 → 0.0.2
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/chats.js
CHANGED
|
@@ -1112,6 +1112,7 @@ export const makeChatsSocket = (config) => {
|
|
|
1112
1112
|
cleanDirtyBits: cleanDirtyBits,
|
|
1113
1113
|
addOrEditContact: addOrEditContact,
|
|
1114
1114
|
removeContact: removeContact,
|
|
1115
|
+
placeholderResendCache: placeholderResendCache,
|
|
1115
1116
|
addLabel: addLabel,
|
|
1116
1117
|
addChatLabel: addChatLabel,
|
|
1117
1118
|
removeChatLabel: removeChatLabel,
|
|
@@ -39,10 +39,11 @@ import {
|
|
|
39
39
|
buildMergedTcTokenIndexWrite,
|
|
40
40
|
generateCsToken,
|
|
41
41
|
unixTimestampSeconds,
|
|
42
|
+
DEF_MEDIA_HOST,
|
|
42
43
|
} from "../Utils/index.js";
|
|
43
44
|
import { AssociationType } from "../Types/index.js";
|
|
44
45
|
import { getUrlInfo } from "../Utils/link-preview.js";
|
|
45
|
-
import { makeKeyedMutex } from "../Utils/make-mutex.js";
|
|
46
|
+
import { makeKeyedMutex, makeMutex } from "../Utils/make-mutex.js";
|
|
46
47
|
import {
|
|
47
48
|
getMessageReportingToken,
|
|
48
49
|
shouldIncludeReportingToken,
|
|
@@ -105,8 +106,12 @@ export const makeMessagesSocket = (config) => {
|
|
|
105
106
|
? new MessageRetryManager(logger, maxMsgRetryCount)
|
|
106
107
|
: null;
|
|
107
108
|
const encryptionMutex = makeKeyedMutex();
|
|
109
|
+
/** Serializes writes to userDevicesCache across USync refresh and device-notification handling. */
|
|
110
|
+
const devicesMutex = makeMutex();
|
|
108
111
|
const inFlightTcTokenIssuance = new Set();
|
|
109
112
|
let mediaConn;
|
|
113
|
+
/** Per-socket media host; updated whenever media_conn is fetched. Defaults to the public WhatsApp host. */
|
|
114
|
+
let mediaHost = DEF_MEDIA_HOST;
|
|
110
115
|
const issuePrivacyTokens = async (jids, timestamp) => {
|
|
111
116
|
const t = (timestamp ?? unixTimestampSeconds()).toString();
|
|
112
117
|
const result = await query({
|
|
@@ -161,6 +166,9 @@ export const makeMessagesSocket = (config) => {
|
|
|
161
166
|
fetchDate: new Date(),
|
|
162
167
|
};
|
|
163
168
|
logger.debug("fetched media conn");
|
|
169
|
+
if (node.hosts[0]) {
|
|
170
|
+
mediaHost = node.hosts[0].hostname;
|
|
171
|
+
}
|
|
164
172
|
return node;
|
|
165
173
|
})();
|
|
166
174
|
}
|
|
@@ -363,18 +371,21 @@ export const makeMessagesSocket = (config) => {
|
|
|
363
371
|
);
|
|
364
372
|
}
|
|
365
373
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
key
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
374
|
+
await devicesMutex.mutex(async () => {
|
|
375
|
+
if (userDevicesCache.mset) {
|
|
376
|
+
await userDevicesCache.mset(
|
|
377
|
+
Object.entries(deviceMap).map(([key, value]) => ({
|
|
378
|
+
key: key,
|
|
379
|
+
value: value,
|
|
380
|
+
})),
|
|
381
|
+
);
|
|
382
|
+
} else {
|
|
383
|
+
for (const key in deviceMap) {
|
|
384
|
+
if (deviceMap[key])
|
|
385
|
+
await userDevicesCache.set(key, deviceMap[key]);
|
|
386
|
+
}
|
|
376
387
|
}
|
|
377
|
-
}
|
|
388
|
+
});
|
|
378
389
|
const userDeviceUpdates = {};
|
|
379
390
|
for (const [userId, devices] of Object.entries(deviceMap)) {
|
|
380
391
|
if (devices && devices.length > 0) {
|
|
@@ -1316,6 +1327,8 @@ export const makeMessagesSocket = (config) => {
|
|
|
1316
1327
|
const waitForMsgMediaUpdate = bindWaitForEvent(ev, "messages.media-update");
|
|
1317
1328
|
return {
|
|
1318
1329
|
...sock,
|
|
1330
|
+
userDevicesCache: userDevicesCache,
|
|
1331
|
+
devicesMutex: devicesMutex,
|
|
1319
1332
|
getPrivacyTokens: getPrivacyTokens,
|
|
1320
1333
|
issuePrivacyTokens: issuePrivacyTokens,
|
|
1321
1334
|
assertSessions: assertSessions,
|
|
@@ -1324,6 +1337,8 @@ export const makeMessagesSocket = (config) => {
|
|
|
1324
1337
|
sendReceipts: sendReceipts,
|
|
1325
1338
|
readMessages: readMessages,
|
|
1326
1339
|
refreshMediaConn: refreshMediaConn,
|
|
1340
|
+
// Function (not getter) so the spread in chats.js preserves the live closure binding.
|
|
1341
|
+
getMediaHost: () => mediaHost,
|
|
1327
1342
|
waUploadToServer: waUploadToServer,
|
|
1328
1343
|
fetchPrivacySettings: fetchPrivacySettings,
|
|
1329
1344
|
sendPeerMessage: sendPeerMessage,
|
|
@@ -1368,7 +1383,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
1368
1383
|
);
|
|
1369
1384
|
}
|
|
1370
1385
|
content.directPath = media.directPath;
|
|
1371
|
-
content.url = getUrlFromDirectPath(content.directPath);
|
|
1386
|
+
content.url = getUrlFromDirectPath(content.directPath, mediaHost);
|
|
1372
1387
|
logger.debug(
|
|
1373
1388
|
{ directPath: media.directPath, key: result.key },
|
|
1374
1389
|
"media update successful",
|
|
@@ -580,7 +580,12 @@ const consolidateEvents = (data) => {
|
|
|
580
580
|
Object.keys(data.historySets.messages).length ||
|
|
581
581
|
Object.keys(data.historySets.contacts).length
|
|
582
582
|
) {
|
|
583
|
-
map["messaging-history.set"] =
|
|
583
|
+
map["messaging-history.set"] = {
|
|
584
|
+
...data.historySets,
|
|
585
|
+
chats: Object.values(data.historySets.chats),
|
|
586
|
+
contacts: Object.values(data.historySets.contacts),
|
|
587
|
+
messages: Object.values(data.historySets.messages),
|
|
588
|
+
};
|
|
584
589
|
}
|
|
585
590
|
if (Object.keys(data.chatUpserts).length)
|
|
586
591
|
map["chats.upsert"] = Object.values(data.chatUpserts);
|
package/lib/Utils/messages.js
CHANGED
|
@@ -975,15 +975,20 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
975
975
|
} else {
|
|
976
976
|
m = await prepareWAMessageMedia(message, options);
|
|
977
977
|
}
|
|
978
|
-
if (
|
|
978
|
+
if (
|
|
979
|
+
hasOptionalProperty(message, "viewOnce") &&
|
|
980
|
+
!!message.viewOnce &&
|
|
981
|
+
!m.viewOnceMessage
|
|
982
|
+
) {
|
|
979
983
|
m = { viewOnceMessage: { message: m } };
|
|
980
984
|
}
|
|
981
985
|
if (
|
|
982
986
|
(hasOptionalProperty(message, "mentions") && message.mentions?.length) ||
|
|
983
987
|
(hasOptionalProperty(message, "mentionAll") && message.mentionAll)
|
|
984
988
|
) {
|
|
985
|
-
const
|
|
986
|
-
const
|
|
989
|
+
const target = m.viewOnceMessage ? m.viewOnceMessage.message : m;
|
|
990
|
+
const messageType = Object.keys(target)[0];
|
|
991
|
+
const key = target[messageType];
|
|
987
992
|
if (key && "contextInfo" in key) {
|
|
988
993
|
key.contextInfo = key.contextInfo || {};
|
|
989
994
|
if (message.mentions?.length) {
|
|
@@ -1431,4 +1436,4 @@ export const assertMediaContent = (content) => {
|
|
|
1431
1436
|
});
|
|
1432
1437
|
}
|
|
1433
1438
|
return mediaContent;
|
|
1434
|
-
};
|
|
1439
|
+
};
|
|
@@ -5,13 +5,24 @@ import { LRUCache } from "lru-cache";
|
|
|
5
5
|
import fs from "fs";
|
|
6
6
|
import path from "path";
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
// Reuse ONE Database connection per auth.db file across every session
|
|
9
|
+
// (sub-bot) in this process, instead of opening a brand-new connection
|
|
10
|
+
// per call. Multiple connections hammering the same WAL-mode file is the
|
|
11
|
+
// most likely cause of the occasional "freeze" — a read/write can end up
|
|
12
|
+
// waiting on SQLITE_BUSY behind another connection's lock, which stalls
|
|
13
|
+
// whatever baileys handler triggered it (looks like the bot hung).
|
|
14
|
+
// This also lets us checkpoint + close cleanly on shutdown, so a killed
|
|
15
|
+
// process doesn't leave the WAL file in a state that causes the next
|
|
16
|
+
// boot to stall while SQLite recovers it.
|
|
17
|
+
const dbPool = new Map();
|
|
18
|
+
let exitHandlersRegistered = false;
|
|
11
19
|
|
|
12
|
-
|
|
13
|
-
const
|
|
20
|
+
const getDb = (folder, DatabaseCtor) => {
|
|
21
|
+
const dbPath = path.resolve(folder, "auth.db");
|
|
22
|
+
let db = dbPool.get(dbPath);
|
|
23
|
+
if (db) return db;
|
|
14
24
|
|
|
25
|
+
db = new DatabaseCtor(dbPath);
|
|
15
26
|
db.pragma("foreign_keys = ON");
|
|
16
27
|
db.pragma("journal_mode = WAL");
|
|
17
28
|
db.pragma("synchronous = NORMAL");
|
|
@@ -19,6 +30,38 @@ export const usePrototypeAuthState = async (config = {}) => {
|
|
|
19
30
|
db.pragma("cache_size = -128000");
|
|
20
31
|
db.pragma("mmap_size = 524288000");
|
|
21
32
|
db.pragma("busy_timeout = 5000");
|
|
33
|
+
dbPool.set(dbPath, db);
|
|
34
|
+
|
|
35
|
+
if (!exitHandlersRegistered) {
|
|
36
|
+
exitHandlersRegistered = true;
|
|
37
|
+
const closeAll = () => {
|
|
38
|
+
for (const conn of dbPool.values()) {
|
|
39
|
+
try {
|
|
40
|
+
conn.pragma("wal_checkpoint(TRUNCATE)");
|
|
41
|
+
conn.close();
|
|
42
|
+
} catch {}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
process.once("SIGINT", () => {
|
|
46
|
+
closeAll();
|
|
47
|
+
process.exit(0);
|
|
48
|
+
});
|
|
49
|
+
process.once("SIGTERM", () => {
|
|
50
|
+
closeAll();
|
|
51
|
+
process.exit(0);
|
|
52
|
+
});
|
|
53
|
+
process.once("beforeExit", closeAll);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return db;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const usePrototypeAuthState = async (config = {}) => {
|
|
60
|
+
const folder = config.folder || "./auth";
|
|
61
|
+
if (!fs.existsSync(folder)) fs.mkdirSync(folder, { recursive: true });
|
|
62
|
+
|
|
63
|
+
const session = config.session || "default";
|
|
64
|
+
const db = getDb(folder, config.Database);
|
|
22
65
|
|
|
23
66
|
db.prepare(
|
|
24
67
|
"CREATE TABLE IF NOT EXISTS baileys_metadata (name TEXT PRIMARY KEY)",
|
|
@@ -145,7 +145,11 @@ const MIXED_NATIVE_FLOW = {
|
|
|
145
145
|
};
|
|
146
146
|
export const getBizBinaryNode = (message, addBizAttributes) => {
|
|
147
147
|
const bizAttributes = {};
|
|
148
|
-
const flowMsg =
|
|
148
|
+
const flowMsg =
|
|
149
|
+
message.interactiveMessage?.nativeFlowMessage ||
|
|
150
|
+
message.interactiveMessage?.carouselMessage?.cards?.find(
|
|
151
|
+
(card) => card?.nativeFlowMessage?.buttons?.length
|
|
152
|
+
)?.nativeFlowMessage;
|
|
149
153
|
const firstButtonName = flowMsg?.buttons?.[0]?.name;
|
|
150
154
|
const qualityContent = {
|
|
151
155
|
tag: "quality_control",
|
|
@@ -199,4 +203,4 @@ export const getBizBinaryNode = (message, addBizAttributes) => {
|
|
|
199
203
|
};
|
|
200
204
|
}
|
|
201
205
|
return { tag: "biz", attrs: bizAttributes, content: [qualityContent] };
|
|
202
|
-
};
|
|
206
|
+
};
|