socketon 1.31.2-rc → 1.51.16
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/README.md +313 -159
- package/WAProto/WAProto.proto +5311 -0
- package/WAProto/index.js +65801 -141371
- package/lib/Defaults/index.js +117 -141
- package/lib/KeyDB/BinarySearch.js +20 -0
- package/lib/KeyDB/KeyedDB.js +167 -0
- package/lib/KeyDB/index.js +4 -0
- package/lib/Signal/Group/ciphertext-message.js +12 -14
- package/lib/Signal/Group/group-session-builder.js +10 -42
- package/lib/Signal/Group/group_cipher.js +75 -87
- package/lib/Signal/Group/index.js +13 -57
- package/lib/Signal/Group/keyhelper.js +17 -52
- package/lib/Signal/Group/sender-chain-key.js +27 -33
- package/lib/Signal/Group/sender-key-distribution-message.js +62 -63
- package/lib/Signal/Group/sender-key-message.js +65 -66
- package/lib/Signal/Group/sender-key-name.js +45 -44
- package/lib/Signal/Group/sender-key-record.js +39 -49
- package/lib/Signal/Group/sender-key-state.js +80 -93
- package/lib/Signal/Group/sender-message-key.js +27 -28
- package/lib/Signal/libsignal.js +313 -163
- package/lib/Signal/lid-mapping.js +155 -0
- package/lib/Socket/Client/index.js +4 -19
- package/lib/Socket/Client/types.js +13 -0
- package/lib/Socket/Client/websocket.js +52 -0
- package/lib/Socket/Client/websocket.js.bak +53 -0
- package/lib/Socket/business.js +359 -242
- package/lib/Socket/chats.js +846 -935
- package/lib/Socket/communities.js +413 -0
- package/lib/Socket/groups.js +304 -309
- package/lib/Socket/index.js +15 -10
- package/lib/Socket/messages-recv.js +1107 -1054
- package/lib/Socket/messages-send.js +639 -448
- package/lib/Socket/mex.js +45 -0
- package/lib/Socket/newsletter.js +240 -324
- package/lib/Socket/socket.js +794 -651
- package/lib/Socket/socketon.js +402 -0
- package/lib/Store/index.js +6 -10
- package/lib/Store/make-cache-manager-store.js +73 -81
- package/lib/Store/make-in-memory-store.js +286 -423
- package/lib/Store/make-ordered-dictionary.js +77 -79
- package/lib/Store/object-repository.js +24 -26
- package/lib/Types/Auth.js +3 -2
- package/lib/Types/Bussines.js +3 -0
- package/lib/Types/Call.js +3 -2
- package/lib/Types/Chat.js +9 -4
- package/lib/Types/Contact.js +3 -2
- package/lib/Types/Events.js +3 -2
- package/lib/Types/GroupMetadata.js +3 -2
- package/lib/Types/Label.js +24 -26
- package/lib/Types/LabelAssociation.js +6 -8
- package/lib/Types/Message.js +12 -9
- package/lib/Types/Newsletter.js +33 -38
- package/lib/Types/Newsletter.js.bak +33 -0
- package/lib/Types/Product.js +3 -2
- package/lib/Types/Signal.js +3 -2
- package/lib/Types/Socket.js +4 -2
- package/lib/Types/State.js +11 -2
- package/lib/Types/USync.js +3 -2
- package/lib/Types/index.js +27 -41
- package/lib/Utils/auth-utils.js +211 -198
- package/lib/Utils/baileys-event-stream.js +42 -61
- package/lib/Utils/browser-utils.js +25 -0
- package/lib/Utils/business.js +213 -214
- package/lib/Utils/chat-utils.js +710 -687
- package/lib/Utils/crypto.js +112 -133
- package/lib/Utils/decode-wa-message.js +252 -183
- package/lib/Utils/decode-wa-message.js.bak +267 -0
- package/lib/Utils/event-buffer.js +510 -496
- package/lib/Utils/generics.js +319 -392
- package/lib/Utils/history.js +83 -92
- package/lib/Utils/index.js +21 -33
- package/lib/Utils/link-preview.js +71 -83
- package/lib/Utils/logger.js +5 -7
- package/lib/Utils/lt-hash.js +40 -46
- package/lib/Utils/make-mutex.js +34 -41
- package/lib/Utils/message-retry-manager.js +113 -0
- package/lib/Utils/messages-media.js +550 -768
- package/lib/Utils/messages.js +354 -263
- package/lib/Utils/noise-handler.js +138 -149
- package/lib/Utils/pre-key-manager.js +85 -0
- package/lib/Utils/process-message.js +323 -303
- package/lib/Utils/signal.js +149 -141
- package/lib/Utils/use-multi-file-auth-state.js +95 -103
- package/lib/Utils/validate-connection.js +183 -214
- package/lib/WABinary/constants.js +1298 -35
- package/lib/WABinary/decode.js +237 -249
- package/lib/WABinary/encode.js +213 -260
- package/lib/WABinary/generic-utils.js +56 -65
- package/lib/WABinary/index.js +7 -21
- package/lib/WABinary/jid-utils.js +89 -58
- package/lib/WABinary/types.js +3 -2
- package/lib/WAM/BinaryInfo.js +10 -12
- package/lib/WAM/constants.js +22851 -15348
- package/lib/WAM/encode.js +135 -136
- package/lib/WAM/index.js +5 -19
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +28 -30
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +49 -53
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +27 -28
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +36 -39
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +50 -50
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +26 -20
- package/lib/WAUSync/Protocols/index.js +6 -20
- package/lib/WAUSync/USyncQuery.js +86 -85
- package/lib/WAUSync/USyncUser.js +23 -25
- package/lib/WAUSync/index.js +5 -19
- package/lib/index.js +27 -35
- package/package.json +85 -95
- package/engine-requirements.js +0 -10
- package/lib/Defaults/baileys-version.json +0 -3
- package/lib/Defaults/index.d.ts +0 -53
- package/lib/Defaults/phonenumber-mcc.json +0 -223
- package/lib/Signal/Group/ciphertext-message.d.ts +0 -9
- package/lib/Signal/Group/group-session-builder.d.ts +0 -14
- package/lib/Signal/Group/group_cipher.d.ts +0 -17
- package/lib/Signal/Group/index.d.ts +0 -11
- package/lib/Signal/Group/keyhelper.d.ts +0 -10
- package/lib/Signal/Group/queue-job.d.ts +0 -1
- package/lib/Signal/Group/queue-job.js +0 -57
- package/lib/Signal/Group/sender-chain-key.d.ts +0 -13
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +0 -16
- package/lib/Signal/Group/sender-key-message.d.ts +0 -18
- package/lib/Signal/Group/sender-key-name.d.ts +0 -17
- package/lib/Signal/Group/sender-key-record.d.ts +0 -30
- package/lib/Signal/Group/sender-key-state.d.ts +0 -38
- package/lib/Signal/Group/sender-message-key.d.ts +0 -11
- package/lib/Signal/libsignal.d.ts +0 -3
- package/lib/Socket/Client/abstract-socket-client.d.ts +0 -17
- package/lib/Socket/Client/abstract-socket-client.js +0 -13
- package/lib/Socket/Client/index.d.ts +0 -3
- package/lib/Socket/Client/mobile-socket-client.d.ts +0 -13
- package/lib/Socket/Client/mobile-socket-client.js +0 -65
- package/lib/Socket/Client/web-socket-client.d.ts +0 -12
- package/lib/Socket/Client/web-socket-client.js +0 -62
- package/lib/Socket/business.d.ts +0 -171
- package/lib/Socket/chats.d.ts +0 -267
- package/lib/Socket/dugong.d.ts +0 -254
- package/lib/Socket/dugong.js +0 -484
- package/lib/Socket/groups.d.ts +0 -115
- package/lib/Socket/index.d.ts +0 -173
- package/lib/Socket/messages-recv.d.ts +0 -161
- package/lib/Socket/messages-send.d.ts +0 -149
- package/lib/Socket/newsletter.d.ts +0 -134
- package/lib/Socket/registration.d.ts +0 -267
- package/lib/Socket/registration.js +0 -166
- package/lib/Socket/socket.d.ts +0 -43
- package/lib/Socket/usync.d.ts +0 -36
- package/lib/Socket/usync.js +0 -70
- package/lib/Store/index.d.ts +0 -3
- package/lib/Store/make-cache-manager-store.d.ts +0 -13
- package/lib/Store/make-in-memory-store.d.ts +0 -118
- package/lib/Store/make-ordered-dictionary.d.ts +0 -13
- package/lib/Store/object-repository.d.ts +0 -10
- package/lib/Types/Auth.d.ts +0 -110
- package/lib/Types/Call.d.ts +0 -13
- package/lib/Types/Chat.d.ts +0 -102
- package/lib/Types/Contact.d.ts +0 -19
- package/lib/Types/Events.d.ts +0 -157
- package/lib/Types/GroupMetadata.d.ts +0 -55
- package/lib/Types/Label.d.ts +0 -35
- package/lib/Types/LabelAssociation.d.ts +0 -29
- package/lib/Types/Message.d.ts +0 -273
- package/lib/Types/Newsletter.d.ts +0 -103
- package/lib/Types/Product.d.ts +0 -78
- package/lib/Types/Signal.d.ts +0 -57
- package/lib/Types/Socket.d.ts +0 -111
- package/lib/Types/State.d.ts +0 -27
- package/lib/Types/USync.d.ts +0 -25
- package/lib/Types/index.d.ts +0 -57
- package/lib/Utils/auth-utils.d.ts +0 -18
- package/lib/Utils/baileys-event-stream.d.ts +0 -16
- package/lib/Utils/business.d.ts +0 -22
- package/lib/Utils/chat-utils.d.ts +0 -71
- package/lib/Utils/crypto.d.ts +0 -41
- package/lib/Utils/decode-wa-message.d.ts +0 -19
- package/lib/Utils/event-buffer.d.ts +0 -35
- package/lib/Utils/generics.d.ts +0 -92
- package/lib/Utils/generics.js.bak +0 -433
- package/lib/Utils/history.d.ts +0 -15
- package/lib/Utils/index.d.ts +0 -17
- package/lib/Utils/link-preview.d.ts +0 -21
- package/lib/Utils/logger.d.ts +0 -4
- package/lib/Utils/lt-hash.d.ts +0 -12
- package/lib/Utils/make-mutex.d.ts +0 -7
- package/lib/Utils/messages-media.d.ts +0 -116
- package/lib/Utils/messages.d.ts +0 -77
- package/lib/Utils/noise-handler.d.ts +0 -21
- package/lib/Utils/process-message.d.ts +0 -41
- package/lib/Utils/signal.d.ts +0 -32
- package/lib/Utils/use-multi-file-auth-state.d.ts +0 -13
- package/lib/Utils/validate-connection.d.ts +0 -11
- package/lib/Utils/validate-connection.js.bak +0 -237
- package/lib/WABinary/constants.d.ts +0 -30
- package/lib/WABinary/decode.d.ts +0 -7
- package/lib/WABinary/encode.d.ts +0 -3
- package/lib/WABinary/generic-utils.d.ts +0 -17
- package/lib/WABinary/index.d.ts +0 -5
- package/lib/WABinary/jid-utils.d.ts +0 -31
- package/lib/WABinary/types.d.ts +0 -18
- package/lib/WAM/BinaryInfo.d.ts +0 -17
- package/lib/WAM/constants.d.ts +0 -38
- package/lib/WAM/encode.d.ts +0 -3
- package/lib/WAM/index.d.ts +0 -3
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +0 -9
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +0 -22
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +0 -12
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +0 -12
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +0 -25
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +0 -8
- package/lib/WAUSync/Protocols/index.d.ts +0 -4
- package/lib/WAUSync/USyncQuery.d.ts +0 -28
- package/lib/WAUSync/USyncUser.d.ts +0 -12
- package/lib/WAUSync/index.d.ts +0 -3
- package/lib/index.d.ts +0 -12
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
//=======================================================//
|
|
2
|
+
import makeWASocket from "./index.js";
|
|
3
|
+
import { useMultiFileAuthState } from "../Utils/use-multi-file-auth-state.js";
|
|
4
|
+
import { Browsers } from "../Utils/browser-utils.js";
|
|
5
|
+
import { DisconnectReason } from "../Types/index.js";
|
|
6
|
+
import { downloadContentFromMessage } from "../Utils/messages-media.js";
|
|
7
|
+
import { jidDecode, jidEncode } from "../WABinary/index.js";
|
|
8
|
+
import { proto } from "../../WAProto/index.js";
|
|
9
|
+
import pino from "pino";
|
|
10
|
+
import fs from "fs/promises";
|
|
11
|
+
import path from "path";
|
|
12
|
+
//=======================================================//
|
|
13
|
+
|
|
14
|
+
const DEFAULT_CONFIG = {
|
|
15
|
+
connectTimeoutMs: 30000,
|
|
16
|
+
keepAliveIntervalMs: 30000,
|
|
17
|
+
maxMsgRetryCount: 5,
|
|
18
|
+
enableAutoReconnect: true,
|
|
19
|
+
enableMetadataCache: true,
|
|
20
|
+
syncFullHistory: false,
|
|
21
|
+
browser: Browsers.ubuntu("Chrome")
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const MAX_RECONNECT_ATTEMPTS = 10;
|
|
25
|
+
const BASE_RECONNECT_DELAY = 5000;
|
|
26
|
+
|
|
27
|
+
let reconnectAttempts = 0;
|
|
28
|
+
let reconnectScheduled = false;
|
|
29
|
+
let groupMetadataCache = new Map();
|
|
30
|
+
|
|
31
|
+
export const makeWASocketon = async (config = {}) => {
|
|
32
|
+
const { sessionDir, pairingNumber, pairingCode, onMessage, onConnection, onGroupJoin, onGroupLeave, onError } = config;
|
|
33
|
+
|
|
34
|
+
// Validasi config
|
|
35
|
+
if (!sessionDir) {
|
|
36
|
+
throw new Error("sessionDir is required");
|
|
37
|
+
}
|
|
38
|
+
if (!pairingNumber) {
|
|
39
|
+
throw new Error("pairingNumber is required");
|
|
40
|
+
}
|
|
41
|
+
if (!onMessage || typeof onMessage !== "function") {
|
|
42
|
+
throw new Error("onMessage callback is required and must be a function");
|
|
43
|
+
}
|
|
44
|
+
if (pairingCode && pairingCode.length !== 8) {
|
|
45
|
+
throw new Error("pairingCode must be 8 characters long");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Create session directory if not exists
|
|
49
|
+
await fs.mkdir(sessionDir, { recursive: true });
|
|
50
|
+
|
|
51
|
+
// Initialize auth state
|
|
52
|
+
const { state, saveCreds } = await useMultiFileAuthState(sessionDir);
|
|
53
|
+
|
|
54
|
+
// Setup logger
|
|
55
|
+
const logger = config.logger || pino({ level: "info" }).child({ service: "socketon" });
|
|
56
|
+
|
|
57
|
+
// Initialize socket
|
|
58
|
+
const sock = makeWASocket({
|
|
59
|
+
...DEFAULT_CONFIG,
|
|
60
|
+
...config,
|
|
61
|
+
auth: state,
|
|
62
|
+
logger,
|
|
63
|
+
printQRInTerminal: false,
|
|
64
|
+
defaultQueryTimeoutMs: 60000
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Enhanced helpers
|
|
68
|
+
sock.sessionDir = sessionDir;
|
|
69
|
+
sock.sessionId = path.basename(sessionDir);
|
|
70
|
+
sock.socketonConfig = { sessionDir, pairingNumber, pairingCode };
|
|
71
|
+
|
|
72
|
+
// Message serializer
|
|
73
|
+
sock.serialize = (msg) => {
|
|
74
|
+
const { key, message, pushName, participant } = msg;
|
|
75
|
+
const m = {
|
|
76
|
+
id: key.id,
|
|
77
|
+
remoteJid: key.remoteJid,
|
|
78
|
+
fromMe: key.fromMe,
|
|
79
|
+
timestamp: msg.messageTimestamp,
|
|
80
|
+
pushName: pushName || "",
|
|
81
|
+
text: message?.conversation ||
|
|
82
|
+
message?.extendedTextMessage?.text ||
|
|
83
|
+
message?.imageMessage?.caption ||
|
|
84
|
+
message?.videoMessage?.caption || "",
|
|
85
|
+
quoted: null,
|
|
86
|
+
mentionedJids: [],
|
|
87
|
+
isGroup: key.remoteJid?.endsWith("@g.us"),
|
|
88
|
+
isNewsletter: key.remoteJid?.endsWith("@newsletter"),
|
|
89
|
+
author: participant || key.remoteJid?.split(":")[0]
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Parse quoted message
|
|
93
|
+
if (message?.extendedTextMessage?.contextInfo) {
|
|
94
|
+
const { quotedMessage, participant: quotedParticipant } = message.extendedTextMessage.contextInfo;
|
|
95
|
+
if (quotedMessage) {
|
|
96
|
+
m.quoted = {
|
|
97
|
+
id: key.remoteJid,
|
|
98
|
+
participant: quotedParticipant,
|
|
99
|
+
text: quotedMessage?.conversation || quotedMessage?.extendedTextMessage?.text || ""
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Parse mentions
|
|
105
|
+
if (message?.extendedTextMessage?.contextInfo?.mentionedJid) {
|
|
106
|
+
m.mentionedJids = message.extendedTextMessage.contextInfo.mentionedJid;
|
|
107
|
+
} else if (message?.extendedTextMessage?.contextInfo?.mentionedJid) {
|
|
108
|
+
m.mentionedJids = message.extendedTextMessage.contextInfo.mentionedJid;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return m;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// Group metadata cache
|
|
115
|
+
sock.groupMetadataCache = groupMetadataCache;
|
|
116
|
+
sock.getGroupMetadata = async (jid) => {
|
|
117
|
+
if (!jid || !jid.endsWith("@g.us")) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (config.enableMetadataCache !== false && groupMetadataCache.has(jid)) {
|
|
122
|
+
return groupMetadataCache.get(jid);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
const metadata = await sock.groupMetadata(jid);
|
|
127
|
+
if (config.enableMetadataCache !== false) {
|
|
128
|
+
groupMetadataCache.set(jid, metadata);
|
|
129
|
+
}
|
|
130
|
+
return metadata;
|
|
131
|
+
} catch (error) {
|
|
132
|
+
logger.error({ jid, error: error.message }, "Failed to fetch group metadata");
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
sock.clearGroupCache = (jid) => {
|
|
138
|
+
if (jid) {
|
|
139
|
+
groupMetadataCache.delete(jid);
|
|
140
|
+
} else {
|
|
141
|
+
groupMetadataCache.clear();
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// Download media helper
|
|
146
|
+
sock.downloadMedia = async (msg, type, filename) => {
|
|
147
|
+
if (!msg || !msg.url) {
|
|
148
|
+
return Buffer.alloc(0);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
const stream = await downloadContentFromMessage(msg, type || "image");
|
|
153
|
+
let buffer = Buffer.from([]);
|
|
154
|
+
for await (const chunk of stream) {
|
|
155
|
+
buffer = Buffer.concat([buffer, chunk]);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (filename) {
|
|
159
|
+
const filePath = path.join(sessionDir, filename);
|
|
160
|
+
await fs.writeFile(filePath, buffer);
|
|
161
|
+
return filePath;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return buffer;
|
|
165
|
+
} catch (error) {
|
|
166
|
+
logger.error({ error: error.message }, "Failed to download media");
|
|
167
|
+
return Buffer.alloc(0);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
// Decode JID helper
|
|
172
|
+
sock.decodeJid = (jid) => {
|
|
173
|
+
if (!jid) return jid;
|
|
174
|
+
|
|
175
|
+
if (/:\\d+@/gi.test(jid)) {
|
|
176
|
+
const decoded = jidDecode(jid);
|
|
177
|
+
if (decoded?.user && decoded?.server) {
|
|
178
|
+
return jidEncode(decoded.user, decoded.server, decoded.device);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return jid;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
// Enhanced send message
|
|
186
|
+
sock.send = async (jid, content) => {
|
|
187
|
+
return await sock.sendMessage(jid, content);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// Reply helper
|
|
191
|
+
sock.reply = async (msg, text, options = {}) => {
|
|
192
|
+
const jid = msg.remoteJid || msg.chat;
|
|
193
|
+
return await sock.sendMessage(jid, {
|
|
194
|
+
text,
|
|
195
|
+
...options
|
|
196
|
+
}, {
|
|
197
|
+
quoted: msg
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// Forward helper
|
|
202
|
+
sock.forward = async (jid, msg) => {
|
|
203
|
+
return await sock.sendMessage(jid, {
|
|
204
|
+
forward: { key: msg.key, message: msg.message }
|
|
205
|
+
});
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// Presence helper
|
|
209
|
+
sock.setPresence = async (status, jid) => {
|
|
210
|
+
return await sock.sendPresenceUpdate(status, jid);
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// Connection status tracking
|
|
214
|
+
const updateConnectionStatus = (status, data = {}) => {
|
|
215
|
+
const connectionData = { status, ...data, timestamp: Date.now() };
|
|
216
|
+
|
|
217
|
+
if (onConnection && typeof onConnection === "function") {
|
|
218
|
+
onConnection(status, connectionData);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// Exponential backoff reconnect
|
|
223
|
+
const scheduleReconnect = async () => {
|
|
224
|
+
if (reconnectScheduled) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
|
229
|
+
logger.error("Max reconnect attempts reached. Giving up.");
|
|
230
|
+
updateConnectionStatus("failed", { attempts: reconnectAttempts });
|
|
231
|
+
reconnectAttempts = 0;
|
|
232
|
+
reconnectScheduled = false;
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
reconnectScheduled = true;
|
|
237
|
+
const backoffMs = Math.min(
|
|
238
|
+
BASE_RECONNECT_DELAY * Math.pow(2, reconnectAttempts),
|
|
239
|
+
60000
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
logger.info(`Reconnecting in ${backoffMs}ms (attempt ${reconnectAttempts + 1}/${MAX_RECONNECT_ATTEMPTS})`);
|
|
243
|
+
updateConnectionStatus("reconnecting", { attempt: reconnectAttempts + 1, delay: backoffMs });
|
|
244
|
+
|
|
245
|
+
await new Promise(resolve => setTimeout(resolve, backoffMs));
|
|
246
|
+
|
|
247
|
+
reconnectAttempts++;
|
|
248
|
+
reconnectScheduled = false;
|
|
249
|
+
|
|
250
|
+
try {
|
|
251
|
+
logger.info("Attempting to reconnect...");
|
|
252
|
+
await sock.ws.connect();
|
|
253
|
+
} catch (error) {
|
|
254
|
+
logger.error({ error: error.message }, "Reconnect failed");
|
|
255
|
+
scheduleReconnect();
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
// Auto-save credentials
|
|
260
|
+
sock.ev.on("creds.update", saveCreds);
|
|
261
|
+
|
|
262
|
+
// Handle messages
|
|
263
|
+
sock.ev.on("messages.upsert", async ({ messages, type }) => {
|
|
264
|
+
for (const msg of messages) {
|
|
265
|
+
if (!msg.message) continue;
|
|
266
|
+
|
|
267
|
+
const serialized = sock.serialize(msg);
|
|
268
|
+
|
|
269
|
+
try {
|
|
270
|
+
await onMessage(serialized, msg);
|
|
271
|
+
} catch (error) {
|
|
272
|
+
logger.error({ error: error.message, messageId: msg.key.id }, "Error in onMessage handler");
|
|
273
|
+
|
|
274
|
+
if (onError && typeof onError === "function") {
|
|
275
|
+
onError(error, { messageId: msg.key.id, type: "message_handler" });
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// Handle connection updates
|
|
282
|
+
sock.ev.on("connection.update", async (update) => {
|
|
283
|
+
const { connection, lastDisconnect } = update;
|
|
284
|
+
|
|
285
|
+
if (connection === "open") {
|
|
286
|
+
logger.info("Connection opened successfully");
|
|
287
|
+
reconnectAttempts = 0;
|
|
288
|
+
reconnectScheduled = false;
|
|
289
|
+
updateConnectionStatus("open");
|
|
290
|
+
}
|
|
291
|
+
else if (connection === "close") {
|
|
292
|
+
const reason = lastDisconnect?.error?.output?.statusCode;
|
|
293
|
+
logger.info({ reason, error: lastDisconnect?.error?.message }, "Connection closed");
|
|
294
|
+
|
|
295
|
+
if (reason === DisconnectReason.loggedOut) {
|
|
296
|
+
logger.error("Session logged out. Delete session directory and restart.");
|
|
297
|
+
updateConnectionStatus("loggedOut", { reason });
|
|
298
|
+
reconnectAttempts = 0;
|
|
299
|
+
}
|
|
300
|
+
else if (config.enableAutoReconnect !== false) {
|
|
301
|
+
logger.info("Auto-reconnect enabled. Scheduling reconnect...");
|
|
302
|
+
updateConnectionStatus("close", { reason, autoReconnect: true });
|
|
303
|
+
await scheduleReconnect();
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
updateConnectionStatus("close", { reason, autoReconnect: false });
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
else if (connection === "connecting") {
|
|
310
|
+
updateConnectionStatus("connecting");
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// Handle group participants update
|
|
315
|
+
sock.ev.on("group-participants.update", async (update) => {
|
|
316
|
+
const { id, participants, action, author } = update;
|
|
317
|
+
|
|
318
|
+
try {
|
|
319
|
+
const metadata = await sock.getGroupMetadata(id);
|
|
320
|
+
if (metadata) {
|
|
321
|
+
groupMetadataCache.set(id, metadata);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (action === "add") {
|
|
325
|
+
for (const participant of participants) {
|
|
326
|
+
const msg = {
|
|
327
|
+
remoteJid: id,
|
|
328
|
+
participant,
|
|
329
|
+
author,
|
|
330
|
+
action: "add"
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
if (onGroupJoin && typeof onGroupJoin === "function") {
|
|
334
|
+
await onGroupJoin(msg, update);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
else if (action === "remove") {
|
|
339
|
+
for (const participant of participants) {
|
|
340
|
+
const msg = {
|
|
341
|
+
remoteJid: id,
|
|
342
|
+
participant,
|
|
343
|
+
author,
|
|
344
|
+
action: "remove"
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
if (onGroupLeave && typeof onGroupLeave === "function") {
|
|
348
|
+
await onGroupLeave(msg, update);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
} catch (error) {
|
|
353
|
+
logger.error({ error: error.message }, "Error in group-participants handler");
|
|
354
|
+
|
|
355
|
+
if (onError && typeof onError === "function") {
|
|
356
|
+
onError(error, { groupId: id, action, type: "group_handler" });
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
// Request pairing code
|
|
362
|
+
if (!sock.authState?.creds?.registered) {
|
|
363
|
+
logger.info("Device not registered. Requesting pairing code...");
|
|
364
|
+
updateConnectionStatus("requesting_pairing_code");
|
|
365
|
+
|
|
366
|
+
setTimeout(async () => {
|
|
367
|
+
try {
|
|
368
|
+
const code = pairingCode && pairingCode.length === 8
|
|
369
|
+
? await sock.requestPairingCode(pairingNumber.trim(), pairingCode)
|
|
370
|
+
: await sock.requestPairingCode(pairingNumber.trim());
|
|
371
|
+
|
|
372
|
+
logger.info({ pairingNumber, code }, "Pairing code generated");
|
|
373
|
+
updateConnectionStatus("pairing_code_ready", { code, pairingNumber });
|
|
374
|
+
|
|
375
|
+
console.log(`\n═════════════════════════════════════`);
|
|
376
|
+
console.log(` 📱 Pairing Code: ${code}`);
|
|
377
|
+
console.log(` 📞 Number: ${pairingNumber.trim()}`);
|
|
378
|
+
console.log(`═════════════════════════════════════\n`);
|
|
379
|
+
} catch (error) {
|
|
380
|
+
logger.error({ error: error.message }, "Failed to request pairing code");
|
|
381
|
+
|
|
382
|
+
if (onError && typeof onError === "function") {
|
|
383
|
+
onError(error, { type: "pairing_code" });
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}, 3000);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Graceful shutdown
|
|
390
|
+
sock.shutdown = async () => {
|
|
391
|
+
logger.info("Shutting down Socketon...");
|
|
392
|
+
await sock.end();
|
|
393
|
+
reconnectAttempts = 0;
|
|
394
|
+
reconnectScheduled = false;
|
|
395
|
+
groupMetadataCache.clear();
|
|
396
|
+
updateConnectionStatus("shutdown");
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
// Return enhanced socket
|
|
400
|
+
return sock;
|
|
401
|
+
};
|
|
402
|
+
//=======================================================//
|
package/lib/Store/index.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const make_cache_manager_store_1 = __importDefault(require("./make-cache-manager-store"));
|
|
8
|
-
exports.makeCacheManagerAuthState = make_cache_manager_store_1.default;
|
|
9
|
-
const make_in_memory_store_1 = __importDefault(require("./make-in-memory-store"));
|
|
10
|
-
exports.makeInMemoryStore = make_in_memory_store_1.default;
|
|
1
|
+
//===================================//
|
|
2
|
+
export * from "./make-cache-manager-store.js"
|
|
3
|
+
export * from "./make-ordered-dictionary.js"
|
|
4
|
+
export * from "./make-in-memory-store.js"
|
|
5
|
+
export * from "./object-repository.js"
|
|
6
|
+
//===================================//
|
|
@@ -1,83 +1,75 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
set: async (data) => {
|
|
68
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
|
-
const tasks = [];
|
|
70
|
-
for (const category in data) {
|
|
71
|
-
for (const id in data[category]) {
|
|
72
|
-
const value = data[category][id];
|
|
73
|
-
const key = `${category}-${id}`;
|
|
74
|
-
tasks.push(value ? writeData(key, value) : removeData(key));
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
await Promise.all(tasks);
|
|
78
|
-
},
|
|
1
|
+
//===================================//
|
|
2
|
+
import { BufferJSON, initAuthCreds } from "../Utils/index.js";
|
|
3
|
+
import { proto } from "../../WAProto/index.js";
|
|
4
|
+
import { createCache } from "cache-manager";
|
|
5
|
+
import logger from "../Utils/logger.js";
|
|
6
|
+
//===================================//
|
|
7
|
+
export async function makeCacheManagerAuthState(store, sessionKey) {
|
|
8
|
+
const defaultKey = (file) => `${sessionKey}:${file}`
|
|
9
|
+
const databaseConn = await caching(store);
|
|
10
|
+
const writeData = async (file, data) => {
|
|
11
|
+
let ttl
|
|
12
|
+
if (file === "creds") {
|
|
13
|
+
ttl = 63115200
|
|
14
|
+
}
|
|
15
|
+
await databaseConn.set(defaultKey(file), JSON.stringify(data, BufferJSON.replacer), ttl)
|
|
16
|
+
}
|
|
17
|
+
const readData = async (file) => {
|
|
18
|
+
try {
|
|
19
|
+
const data = await databaseConn.get(defaultKey(file))
|
|
20
|
+
if (data) return JSON.parse(data, BufferJSON.reviver)
|
|
21
|
+
return null
|
|
22
|
+
} catch (error) {
|
|
23
|
+
logger.error(error)
|
|
24
|
+
return null
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const removeData = async (file) => {
|
|
28
|
+
try {
|
|
29
|
+
return await databaseConn.del(defaultKey(file))
|
|
30
|
+
} catch (err) {
|
|
31
|
+
logger.error(`Error removing ${file} from session ${sessionKey}`)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const clearState = async () => {
|
|
35
|
+
try {
|
|
36
|
+
const keys = await databaseConn.store.keys(`${sessionKey}*`)
|
|
37
|
+
await Promise.all(keys.map((key) => databaseConn.del(key)))
|
|
38
|
+
} catch (err) {}
|
|
39
|
+
}
|
|
40
|
+
const creds = (await readData("creds")) || initAuthCreds()
|
|
41
|
+
return {
|
|
42
|
+
clearState,
|
|
43
|
+
saveCreds: () => writeData("creds", creds),
|
|
44
|
+
state: {
|
|
45
|
+
creds,
|
|
46
|
+
keys: {
|
|
47
|
+
get: async (type, ids) => {
|
|
48
|
+
const data = {}
|
|
49
|
+
await Promise.all(
|
|
50
|
+
ids.map(async (id) => {
|
|
51
|
+
let value = await readData(`${type}-${id}`)
|
|
52
|
+
if (type === "app-state-sync-key" && value) {
|
|
53
|
+
value = proto.Message.AppStateSyncKeyData.fromObject(value)
|
|
54
|
+
}
|
|
55
|
+
data[id] = value
|
|
56
|
+
})
|
|
57
|
+
)
|
|
58
|
+
return data
|
|
59
|
+
},
|
|
60
|
+
set: async (data) => {
|
|
61
|
+
const tasks = []
|
|
62
|
+
for (const category in data) {
|
|
63
|
+
for (const id in data[category]) {
|
|
64
|
+
const value = data[category][id]
|
|
65
|
+
const key = `${category}-${id}`
|
|
66
|
+
tasks.push(value ? writeData(key, value) : removeData(key))
|
|
79
67
|
}
|
|
68
|
+
}
|
|
69
|
+
await Promise.all(tasks)
|
|
80
70
|
}
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//===================================//
|