jagproject 26.3.23 → 26.3.26
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/WAProto/GenerateStatics.sh +3 -4
- package/WAProto/WAProto.proto +1215 -511
- package/WAProto/fix-imports.js +73 -0
- package/WAProto/index.d.ts +14017 -0
- package/WAProto/index.js +64857 -145167
- package/engine-requirements.js +4 -7
- package/lib/Defaults/index.d.ts +74 -0
- package/lib/Defaults/index.js +49 -35
- package/lib/Defaults/phonenumber-mcc.json +223 -0
- package/lib/Defaults/wileys-version.json +2 -2
- package/lib/Signal/Group/ciphertext-message.d.ts +10 -0
- package/lib/Signal/Group/group-session-builder.d.ts +15 -0
- package/lib/Signal/Group/group-session-builder.js +5 -3
- package/lib/Signal/Group/group_cipher.d.ts +17 -0
- package/lib/Signal/Group/group_cipher.js +35 -46
- package/lib/Signal/Group/index.d.ts +12 -0
- package/lib/Signal/Group/index.js +21 -21
- package/lib/Signal/Group/keyhelper.d.ts +11 -0
- package/lib/Signal/Group/keyhelper.js +2 -2
- package/lib/Signal/Group/sender-chain-key.d.ts +14 -0
- package/lib/Signal/Group/sender-chain-key.js +5 -10
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +17 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +7 -7
- package/lib/Signal/Group/sender-key-message.d.ts +19 -0
- package/lib/Signal/Group/sender-key-message.js +8 -8
- package/lib/Signal/Group/sender-key-name.d.ts +18 -0
- package/lib/Signal/Group/sender-key-record.d.ts +31 -0
- package/lib/Signal/Group/sender-key-record.js +7 -16
- package/lib/Signal/Group/sender-key-state.d.ts +39 -0
- package/lib/Signal/Group/sender-key-state.js +25 -37
- package/lib/Signal/Group/sender-message-key.d.ts +12 -0
- package/lib/Signal/Group/sender-message-key.js +2 -2
- package/lib/Signal/libsignal.d.ts +5 -0
- package/lib/Signal/libsignal.js +358 -54
- package/lib/Signal/lid-mapping.d.ts +19 -0
- package/lib/Signal/lid-mapping.js +274 -0
- package/lib/Socket/Client/index.d.ts +3 -0
- package/lib/Socket/Client/index.js +2 -2
- package/lib/Socket/Client/types.d.ts +16 -0
- package/lib/Socket/Client/types.js +1 -0
- package/lib/Socket/Client/websocket.d.ts +13 -0
- package/lib/Socket/Client/websocket.js +18 -30
- package/lib/Socket/business.d.ts +202 -0
- package/lib/Socket/business.js +160 -38
- package/lib/Socket/chats.d.ts +111 -0
- package/lib/Socket/chats.js +497 -314
- package/lib/Socket/communities.d.ts +258 -0
- package/lib/Socket/communities.js +438 -0
- package/lib/Socket/community.js +333 -0
- package/lib/Socket/groups.d.ts +150 -0
- package/lib/Socket/groups.js +229 -91
- package/lib/Socket/index.d.ts +245 -0
- package/lib/Socket/index.js +9 -6
- package/lib/Socket/messages-recv.d.ts +187 -0
- package/lib/Socket/messages-recv.js +1105 -501
- package/lib/Socket/messages-send.d.ts +183 -0
- package/lib/Socket/messages-send.js +1181 -501
- package/lib/Socket/mex.d.ts +3 -0
- package/lib/Socket/mex.js +45 -0
- package/lib/Socket/newsletter.d.ts +160 -0
- package/lib/Socket/newsletter.js +227 -200
- package/lib/Socket/socket.d.ts +55 -0
- package/lib/Socket/socket.js +507 -206
- package/lib/Socket/usync.js +6 -6
- package/lib/Store/index.js +17 -5
- package/lib/Store/make-cache-manager-store.js +83 -0
- package/lib/Store/make-in-memory-store.js +48 -89
- package/lib/Store/make-ordered-dictionary.js +1 -1
- package/lib/Types/Auth.d.ts +116 -0
- package/lib/Types/Bussines.d.ts +25 -0
- package/lib/Types/Bussines.js +2 -0
- package/lib/Types/Call.d.ts +15 -0
- package/lib/Types/Chat.d.ts +123 -0
- package/lib/Types/Chat.js +7 -1
- package/lib/Types/Contact.d.ts +24 -0
- package/lib/Types/Events.d.ts +237 -0
- package/lib/Types/Events.js +1 -0
- package/lib/Types/GroupMetadata.d.ts +67 -0
- package/lib/Types/Label.d.ts +47 -0
- package/lib/Types/Label.js +1 -3
- package/lib/Types/LabelAssociation.d.ts +30 -0
- package/lib/Types/LabelAssociation.js +1 -3
- package/lib/Types/Message.d.ts +305 -0
- package/lib/Types/Message.js +9 -5
- package/lib/Types/MexUpdates.js +11 -0
- package/lib/Types/Newsletter.d.ts +135 -0
- package/lib/Types/Newsletter.js +36 -11
- package/lib/Types/Product.d.ts +79 -0
- package/lib/Types/Signal.d.ts +76 -0
- package/lib/Types/Signal.js +1 -0
- package/lib/Types/Socket.d.ts +133 -0
- package/lib/Types/Socket.js +1 -0
- package/lib/Types/State.d.ts +39 -0
- package/lib/Types/State.js +12 -0
- package/lib/Types/USync.d.ts +26 -0
- package/lib/Types/USync.js +1 -0
- package/lib/Types/index.d.ts +65 -0
- package/lib/Types/index.js +14 -14
- package/lib/Utils/audioToBuffer.js +31 -0
- package/lib/Utils/auth-utils.d.ts +19 -0
- package/lib/Utils/auth-utils.js +222 -123
- package/lib/Utils/baileys-event-stream.js +60 -0
- package/lib/Utils/bridge-runtime.d.ts +1 -0
- package/lib/Utils/bridge-runtime.js +14 -0
- package/lib/Utils/browser-utils.d.ts +4 -0
- package/lib/Utils/browser-utils.js +38 -29
- package/lib/Utils/business.d.ts +23 -0
- package/lib/Utils/business.js +54 -48
- package/lib/Utils/chat-utils.d.ts +70 -0
- package/lib/Utils/chat-utils.js +284 -189
- package/lib/Utils/crypto.d.ts +37 -0
- package/lib/Utils/crypto.js +16 -41
- package/lib/Utils/decode-wa-message.d.ts +48 -0
- package/lib/Utils/decode-wa-message.js +128 -48
- package/lib/Utils/event-buffer.d.ts +34 -0
- package/lib/Utils/event-buffer.js +124 -62
- package/lib/Utils/generics.d.ts +91 -0
- package/lib/Utils/generics.js +154 -138
- package/lib/Utils/history.d.ts +22 -0
- package/lib/Utils/history.js +77 -34
- package/lib/Utils/identity-change-handler.d.ts +37 -0
- package/lib/Utils/identity-change-handler.js +54 -0
- package/lib/Utils/index.d.ts +22 -0
- package/lib/Utils/index.js +32 -19
- package/lib/Utils/link-preview.d.ts +21 -0
- package/lib/Utils/link-preview.js +12 -17
- package/lib/Utils/logger.d.ts +13 -0
- package/lib/Utils/lt-hash.d.ts +8 -0
- package/lib/Utils/lt-hash.js +2 -43
- package/lib/Utils/make-mutex.d.ts +9 -0
- package/lib/Utils/make-mutex.js +21 -27
- package/lib/Utils/message-retry-manager.d.ts +110 -0
- package/lib/Utils/message-retry-manager.js +143 -45
- package/lib/Utils/messages-media.d.ts +130 -0
- package/lib/Utils/messages-media.js +429 -502
- package/lib/Utils/messages-newsletter.d.ts +84 -0
- package/lib/Utils/messages-newsletter.js +295 -0
- package/lib/Utils/messages.d.ts +92 -0
- package/lib/Utils/messages.js +1025 -674
- package/lib/Utils/noise-handler.d.ts +20 -0
- package/lib/Utils/noise-handler.js +145 -91
- package/lib/Utils/pre-key-manager.d.ts +28 -0
- package/lib/Utils/pre-key-manager.js +112 -0
- package/lib/Utils/process-message.d.ts +60 -0
- package/lib/Utils/process-message.js +316 -184
- package/lib/Utils/reporting-utils.d.ts +11 -0
- package/lib/Utils/reporting-utils.js +262 -0
- package/lib/Utils/resolve-jid.d.ts +43 -0
- package/lib/Utils/resolve-jid.js +95 -0
- package/lib/Utils/rust-bridge-shim.d.ts +22 -0
- package/lib/Utils/rust-bridge-shim.js +70 -0
- package/lib/Utils/serial-task-queue.js +29 -0
- package/lib/Utils/signal.d.ts +34 -0
- package/lib/Utils/signal.js +56 -39
- package/lib/Utils/streamToBuffer.js +17 -0
- package/lib/Utils/sync-action-utils.d.ts +19 -0
- package/lib/Utils/sync-action-utils.js +52 -0
- package/lib/Utils/tc-token-utils.d.ts +12 -0
- package/lib/Utils/tc-token-utils.js +20 -0
- package/lib/Utils/use-mongo-file-auth-state.js +71 -0
- package/lib/Utils/use-multi-file-auth-state.d.ts +13 -0
- package/lib/Utils/use-multi-file-auth-state.js +11 -12
- package/lib/Utils/use-single-file-auth-state.js +73 -0
- package/lib/Utils/validate-connection.d.ts +11 -0
- package/lib/Utils/validate-connection.js +59 -82
- package/lib/Utils/wileys-event-stream.js +1 -61
- package/lib/WABinary/constants.d.ts +28 -0
- package/lib/WABinary/decode.d.ts +7 -0
- package/lib/WABinary/decode.js +39 -4
- package/lib/WABinary/encode.d.ts +3 -0
- package/lib/WABinary/encode.js +17 -11
- package/lib/WABinary/generic-utils.d.ts +15 -0
- package/lib/WABinary/generic-utils.js +46 -18
- package/lib/WABinary/index.d.ts +6 -0
- package/lib/WABinary/index.js +9 -5
- package/lib/WABinary/jid-utils.d.ts +48 -0
- package/lib/WABinary/jid-utils.js +67 -37
- package/lib/WABinary/types.d.ts +19 -0
- package/lib/WABinary/types.js +34 -0
- package/lib/WAM/BinaryInfo.d.ts +9 -0
- package/lib/WAM/constants.d.ts +40 -0
- package/lib/WAM/constants.js +19183 -11678
- package/lib/WAM/encode.d.ts +3 -0
- package/lib/WAM/encode.js +15 -17
- package/lib/WAM/index.d.ts +4 -0
- package/lib/WAM/index.js +3 -3
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +10 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +6 -6
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +23 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +9 -9
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +13 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +6 -6
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +13 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +7 -8
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +26 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +18 -17
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +10 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +11 -3
- package/lib/WAUSync/Protocols/index.d.ts +5 -0
- package/lib/WAUSync/Protocols/index.js +6 -4
- package/lib/WAUSync/USyncQuery.d.ts +29 -0
- package/lib/WAUSync/USyncQuery.js +38 -30
- package/lib/WAUSync/USyncUser.d.ts +13 -0
- package/lib/WAUSync/index.d.ts +4 -0
- package/lib/WAUSync/index.js +3 -3
- package/lib/index.d.ts +12 -0
- package/lib/index.js +3 -5
- package/package.json +7 -4
- package/LICENSE +0 -21
package/lib/Socket/chats.js
CHANGED
|
@@ -4,46 +4,45 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.makeChatsSocket = void 0;
|
|
7
|
-
const boom_1 = require("@hapi/boom");
|
|
8
7
|
const node_cache_1 = __importDefault(require("@cacheable/node-cache"));
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
8
|
+
const boom_1 = require("@hapi/boom");
|
|
9
|
+
const index_js_1 = require("../../WAProto/index.js");
|
|
10
|
+
const index_js_2 = require("../Defaults/index.js");
|
|
11
|
+
const index_js_3 = require("../Types/index.js");
|
|
12
|
+
const State_js_1 = require("../Types/State.js");
|
|
13
|
+
const index_js_4 = require("../Utils/index.js");
|
|
14
|
+
const make_mutex_js_1 = require("../Utils/make-mutex.js");
|
|
15
|
+
const process_message_js_1 = __importDefault(require("../Utils/process-message.js"));
|
|
16
|
+
const tc_token_utils_js_1 = require("../Utils/tc-token-utils.js");
|
|
17
|
+
const index_js_5 = require("../WABinary/index.js");
|
|
18
|
+
const index_js_6 = require("../WAUSync/index.js");
|
|
19
|
+
const socket_js_1 = require("./socket.js");
|
|
19
20
|
const MAX_SYNC_ATTEMPTS = 2;
|
|
20
|
-
const SyncState = {
|
|
21
|
-
Connecting: 'connecting',
|
|
22
|
-
AwaitingInitialSync: 'awaiting_initial_sync',
|
|
23
|
-
Syncing: 'syncing',
|
|
24
|
-
Online: 'online'
|
|
25
|
-
};
|
|
26
21
|
const makeChatsSocket = (config) => {
|
|
27
|
-
const { logger, markOnlineOnConnect, fireInitQueries, appStateMacVerification, shouldIgnoreJid, shouldSyncHistoryMessage, } = config;
|
|
28
|
-
const sock = (0,
|
|
29
|
-
const { ev, ws, authState, generateMessageTag, sendNode, query, signalRepository, onUnexpectedError, } = sock;
|
|
22
|
+
const { logger, markOnlineOnConnect, fireInitQueries, appStateMacVerification, shouldIgnoreJid, shouldSyncHistoryMessage, getMessage } = config;
|
|
23
|
+
const sock = (0, socket_js_1.makeSocket)(config);
|
|
24
|
+
const { ev, ws, authState, generateMessageTag, sendNode, query, signalRepository, onUnexpectedError, sendUnifiedSession } = sock;
|
|
30
25
|
let privacySettings;
|
|
31
|
-
let syncState = SyncState.Connecting;
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
let syncState = State_js_1.SyncState.Connecting;
|
|
27
|
+
/** this mutex ensures that messages are processed in order */
|
|
28
|
+
const messageMutex = (0, make_mutex_js_1.makeMutex)();
|
|
29
|
+
/** this mutex ensures that receipts are processed in order */
|
|
30
|
+
const receiptMutex = (0, make_mutex_js_1.makeMutex)();
|
|
31
|
+
/** this mutex ensures that app state patches are processed in order */
|
|
32
|
+
const appStatePatchMutex = (0, make_mutex_js_1.makeMutex)();
|
|
33
|
+
/** this mutex ensures that notifications are processed in order */
|
|
34
|
+
const notificationMutex = (0, make_mutex_js_1.makeMutex)();
|
|
35
|
+
// Timeout for AwaitingInitialSync state
|
|
34
36
|
let awaitingSyncTimeout;
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const receivedMessageDedupCache = new node_cache_1.default({
|
|
41
|
-
stdTTL: 3 * 60,
|
|
42
|
-
useClones: false
|
|
43
|
-
});
|
|
37
|
+
const placeholderResendCache = config.placeholderResendCache ||
|
|
38
|
+
new node_cache_1.default({
|
|
39
|
+
stdTTL: index_js_2.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
|
|
40
|
+
useClones: false
|
|
41
|
+
});
|
|
44
42
|
if (!config.placeholderResendCache) {
|
|
45
43
|
config.placeholderResendCache = placeholderResendCache;
|
|
46
44
|
}
|
|
45
|
+
/** helper function to fetch the given app state sync key */
|
|
47
46
|
const getAppStateSyncKey = async (keyId) => {
|
|
48
47
|
const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId]);
|
|
49
48
|
return key;
|
|
@@ -54,26 +53,26 @@ const makeChatsSocket = (config) => {
|
|
|
54
53
|
tag: 'iq',
|
|
55
54
|
attrs: {
|
|
56
55
|
xmlns: 'privacy',
|
|
57
|
-
to:
|
|
56
|
+
to: index_js_5.S_WHATSAPP_NET,
|
|
58
57
|
type: 'get'
|
|
59
58
|
},
|
|
60
|
-
content: [
|
|
61
|
-
{ tag: 'privacy', attrs: {} }
|
|
62
|
-
]
|
|
59
|
+
content: [{ tag: 'privacy', attrs: {} }]
|
|
63
60
|
});
|
|
64
|
-
privacySettings = (0,
|
|
61
|
+
privacySettings = (0, index_js_5.reduceBinaryNodeToDictionary)(content?.[0], 'category');
|
|
65
62
|
}
|
|
66
63
|
return privacySettings;
|
|
67
64
|
};
|
|
65
|
+
/** helper function to run a privacy IQ query */
|
|
68
66
|
const privacyQuery = async (name, value) => {
|
|
69
67
|
await query({
|
|
70
68
|
tag: 'iq',
|
|
71
69
|
attrs: {
|
|
72
70
|
xmlns: 'privacy',
|
|
73
|
-
to:
|
|
71
|
+
to: index_js_5.S_WHATSAPP_NET,
|
|
74
72
|
type: 'set'
|
|
75
73
|
},
|
|
76
|
-
content: [
|
|
74
|
+
content: [
|
|
75
|
+
{
|
|
77
76
|
tag: 'privacy',
|
|
78
77
|
attrs: {},
|
|
79
78
|
content: [
|
|
@@ -82,7 +81,8 @@ const makeChatsSocket = (config) => {
|
|
|
82
81
|
attrs: { name, value }
|
|
83
82
|
}
|
|
84
83
|
]
|
|
85
|
-
}
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
86
|
});
|
|
87
87
|
};
|
|
88
88
|
const updateMessagesPrivacy = async (value) => {
|
|
@@ -109,23 +109,22 @@ const makeChatsSocket = (config) => {
|
|
|
109
109
|
const updateGroupsAddPrivacy = async (value) => {
|
|
110
110
|
await privacyQuery('groupadd', value);
|
|
111
111
|
};
|
|
112
|
-
const updateDisableLinkPreviewsPrivacy = async (isPreviewsDisabled) => {
|
|
113
|
-
return chatModify({ disableLinkPreviews: { isPreviewsDisabled } }, '');
|
|
114
|
-
};
|
|
115
112
|
const updateDefaultDisappearingMode = async (duration) => {
|
|
116
113
|
await query({
|
|
117
114
|
tag: 'iq',
|
|
118
115
|
attrs: {
|
|
119
116
|
xmlns: 'disappearing_mode',
|
|
120
|
-
to:
|
|
117
|
+
to: index_js_5.S_WHATSAPP_NET,
|
|
121
118
|
type: 'set'
|
|
122
119
|
},
|
|
123
|
-
content: [
|
|
120
|
+
content: [
|
|
121
|
+
{
|
|
124
122
|
tag: 'disappearing_mode',
|
|
125
123
|
attrs: {
|
|
126
124
|
duration: duration.toString()
|
|
127
125
|
}
|
|
128
|
-
}
|
|
126
|
+
}
|
|
127
|
+
]
|
|
129
128
|
});
|
|
130
129
|
};
|
|
131
130
|
const getBotListV2 = async () => {
|
|
@@ -133,21 +132,23 @@ const makeChatsSocket = (config) => {
|
|
|
133
132
|
tag: 'iq',
|
|
134
133
|
attrs: {
|
|
135
134
|
xmlns: 'bot',
|
|
136
|
-
to:
|
|
135
|
+
to: index_js_5.S_WHATSAPP_NET,
|
|
137
136
|
type: 'get'
|
|
138
137
|
},
|
|
139
|
-
content: [
|
|
138
|
+
content: [
|
|
139
|
+
{
|
|
140
140
|
tag: 'bot',
|
|
141
141
|
attrs: {
|
|
142
142
|
v: '2'
|
|
143
143
|
}
|
|
144
|
-
}
|
|
144
|
+
}
|
|
145
|
+
]
|
|
145
146
|
});
|
|
146
|
-
const botNode = (0,
|
|
147
|
+
const botNode = (0, index_js_5.getBinaryNodeChild)(resp, 'bot');
|
|
147
148
|
const botList = [];
|
|
148
|
-
for (const section of (0,
|
|
149
|
+
for (const section of (0, index_js_5.getBinaryNodeChildren)(botNode, 'section')) {
|
|
149
150
|
if (section.attrs.type === 'all') {
|
|
150
|
-
for (const bot of (0,
|
|
151
|
+
for (const bot of (0, index_js_5.getBinaryNodeChildren)(section, 'bot')) {
|
|
151
152
|
botList.push({
|
|
152
153
|
jid: bot.attrs.jid,
|
|
153
154
|
personaId: bot.attrs['persona_id']
|
|
@@ -157,24 +158,29 @@ const makeChatsSocket = (config) => {
|
|
|
157
158
|
}
|
|
158
159
|
return botList;
|
|
159
160
|
};
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
.
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const phone = `+${jid.replace('+', '').split('@')[0].split(':')[0]}`;
|
|
166
|
-
usyncQuery.withUser(new WAUSync_1.USyncUser().withPhone(phone));
|
|
167
|
-
}
|
|
168
|
-
const results = await sock.executeUSyncQuery(usyncQuery);
|
|
169
|
-
if (results) {
|
|
170
|
-
return results.list.filter((a) => !!a.contact).map(({ contact, id, lid }) => ({ jid: id, exists: contact, lid }));
|
|
161
|
+
const getLidUser = async (jid) => {
|
|
162
|
+
if (!jid)
|
|
163
|
+
throw new boom_1.Boom('Please input a jid user');
|
|
164
|
+
if (!jid.endsWith('@s.whatsapp.net') && !jid.endsWith('@lid')) {
|
|
165
|
+
throw new boom_1.Boom('Invalid JID: Not a user JID!');
|
|
171
166
|
}
|
|
167
|
+
const targetJid = jid.includes('@') ? jid : `${jid}@s.whatsapp.net`;
|
|
168
|
+
const usyncQuery = new index_js_6.USyncQuery();
|
|
169
|
+
usyncQuery.protocols.push({
|
|
170
|
+
name: 'lid',
|
|
171
|
+
getQueryElement: () => ({ tag: 'lid', attrs: {}, content: undefined }),
|
|
172
|
+
getUserElement: () => null,
|
|
173
|
+
parser: (node) => node.attrs.val
|
|
174
|
+
});
|
|
175
|
+
usyncQuery.users.push({ id: targetJid });
|
|
176
|
+
const result = await sock.executeUSyncQuery(usyncQuery);
|
|
177
|
+
if (result)
|
|
178
|
+
return result.list;
|
|
172
179
|
};
|
|
173
180
|
const fetchStatus = async (...jids) => {
|
|
174
|
-
const usyncQuery = new
|
|
175
|
-
.withStatusProtocol();
|
|
181
|
+
const usyncQuery = new index_js_6.USyncQuery().withStatusProtocol();
|
|
176
182
|
for (const jid of jids) {
|
|
177
|
-
usyncQuery.withUser(new
|
|
183
|
+
usyncQuery.withUser(new index_js_6.USyncUser().withId(jid));
|
|
178
184
|
}
|
|
179
185
|
const result = await sock.executeUSyncQuery(usyncQuery);
|
|
180
186
|
if (result) {
|
|
@@ -182,32 +188,35 @@ const makeChatsSocket = (config) => {
|
|
|
182
188
|
}
|
|
183
189
|
};
|
|
184
190
|
const fetchDisappearingDuration = async (...jids) => {
|
|
185
|
-
const usyncQuery = new
|
|
186
|
-
.withDisappearingModeProtocol();
|
|
191
|
+
const usyncQuery = new index_js_6.USyncQuery().withDisappearingModeProtocol();
|
|
187
192
|
for (const jid of jids) {
|
|
188
|
-
usyncQuery.withUser(new
|
|
193
|
+
usyncQuery.withUser(new index_js_6.USyncUser().withId(jid));
|
|
189
194
|
}
|
|
190
195
|
const result = await sock.executeUSyncQuery(usyncQuery);
|
|
191
196
|
if (result) {
|
|
192
197
|
return result.list;
|
|
193
198
|
}
|
|
194
199
|
};
|
|
200
|
+
/** update the profile picture for yourself or a group */
|
|
195
201
|
const updateProfilePicture = async (jid, content, dimensions) => {
|
|
196
202
|
let targetJid;
|
|
197
203
|
if (!jid) {
|
|
198
204
|
throw new boom_1.Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update');
|
|
199
205
|
}
|
|
200
|
-
if ((0,
|
|
201
|
-
targetJid = (0,
|
|
206
|
+
if ((0, index_js_5.jidNormalizedUser)(jid) !== (0, index_js_5.jidNormalizedUser)(authState.creds.me.id)) {
|
|
207
|
+
targetJid = (0, index_js_5.jidNormalizedUser)(jid); // in case it is someone other than us
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
targetJid = undefined;
|
|
202
211
|
}
|
|
203
|
-
const { img } = await (0,
|
|
212
|
+
const { img } = await (0, index_js_4.generateProfilePicture)(content, dimensions);
|
|
204
213
|
await query({
|
|
205
214
|
tag: 'iq',
|
|
206
215
|
attrs: {
|
|
207
|
-
|
|
208
|
-
to: WABinary_1.S_WHATSAPP_NET,
|
|
216
|
+
to: index_js_5.S_WHATSAPP_NET,
|
|
209
217
|
type: 'set',
|
|
210
|
-
xmlns: 'w:profile:picture'
|
|
218
|
+
xmlns: 'w:profile:picture',
|
|
219
|
+
...(targetJid ? { target: targetJid } : {})
|
|
211
220
|
},
|
|
212
221
|
content: [
|
|
213
222
|
{
|
|
@@ -218,29 +227,34 @@ const makeChatsSocket = (config) => {
|
|
|
218
227
|
]
|
|
219
228
|
});
|
|
220
229
|
};
|
|
230
|
+
/** remove the profile picture for yourself or a group */
|
|
221
231
|
const removeProfilePicture = async (jid) => {
|
|
222
232
|
let targetJid;
|
|
223
233
|
if (!jid) {
|
|
224
234
|
throw new boom_1.Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update');
|
|
225
235
|
}
|
|
226
|
-
if ((0,
|
|
227
|
-
targetJid = (0,
|
|
236
|
+
if ((0, index_js_5.jidNormalizedUser)(jid) !== (0, index_js_5.jidNormalizedUser)(authState.creds.me.id)) {
|
|
237
|
+
targetJid = (0, index_js_5.jidNormalizedUser)(jid); // in case it is someone other than us
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
targetJid = undefined;
|
|
228
241
|
}
|
|
229
242
|
await query({
|
|
230
243
|
tag: 'iq',
|
|
231
244
|
attrs: {
|
|
232
|
-
|
|
233
|
-
to: WABinary_1.S_WHATSAPP_NET,
|
|
245
|
+
to: index_js_5.S_WHATSAPP_NET,
|
|
234
246
|
type: 'set',
|
|
235
|
-
xmlns: 'w:profile:picture'
|
|
247
|
+
xmlns: 'w:profile:picture',
|
|
248
|
+
...(targetJid ? { target: targetJid } : {})
|
|
236
249
|
}
|
|
237
250
|
});
|
|
238
251
|
};
|
|
252
|
+
/** update the profile status for yourself */
|
|
239
253
|
const updateProfileStatus = async (status) => {
|
|
240
254
|
await query({
|
|
241
255
|
tag: 'iq',
|
|
242
256
|
attrs: {
|
|
243
|
-
to:
|
|
257
|
+
to: index_js_5.S_WHATSAPP_NET,
|
|
244
258
|
type: 'set',
|
|
245
259
|
xmlns: 'status'
|
|
246
260
|
},
|
|
@@ -261,35 +275,50 @@ const makeChatsSocket = (config) => {
|
|
|
261
275
|
tag: 'iq',
|
|
262
276
|
attrs: {
|
|
263
277
|
xmlns: 'blocklist',
|
|
264
|
-
to:
|
|
278
|
+
to: index_js_5.S_WHATSAPP_NET,
|
|
265
279
|
type: 'get'
|
|
266
280
|
}
|
|
267
281
|
});
|
|
268
|
-
const listNode = (0,
|
|
269
|
-
return (0,
|
|
270
|
-
.map(n => n.attrs.jid);
|
|
282
|
+
const listNode = (0, index_js_5.getBinaryNodeChild)(result, 'list');
|
|
283
|
+
return (0, index_js_5.getBinaryNodeChildren)(listNode, 'item').map(n => n.attrs.jid);
|
|
271
284
|
};
|
|
272
285
|
const updateBlockStatus = async (jid, action) => {
|
|
286
|
+
jid = (0, index_js_5.jidNormalizedUser)(jid);
|
|
287
|
+
// Jika input adalah LID, resolve ke PN dulu
|
|
288
|
+
if (jid.endsWith('@lid')) {
|
|
289
|
+
try {
|
|
290
|
+
const pn = await signalRepository?.lidMapping?.getPNForLID?.(jid).catch(() => null);
|
|
291
|
+
if (pn)
|
|
292
|
+
jid = (0, index_js_5.jidNormalizedUser)(pn);
|
|
293
|
+
}
|
|
294
|
+
catch { }
|
|
295
|
+
}
|
|
296
|
+
const dhash = String(Date.now());
|
|
297
|
+
const itemAttrs = {
|
|
298
|
+
dhash,
|
|
299
|
+
action,
|
|
300
|
+
jid, // selalu PN
|
|
301
|
+
};
|
|
302
|
+
// Block: tambah pn_jid juga
|
|
303
|
+
if (action === 'block') {
|
|
304
|
+
itemAttrs.pn_jid = jid;
|
|
305
|
+
}
|
|
273
306
|
await query({
|
|
274
307
|
tag: 'iq',
|
|
275
308
|
attrs: {
|
|
276
309
|
xmlns: 'blocklist',
|
|
277
|
-
to:
|
|
310
|
+
to: index_js_5.S_WHATSAPP_NET,
|
|
278
311
|
type: 'set'
|
|
279
312
|
},
|
|
280
313
|
content: [
|
|
281
314
|
{
|
|
282
315
|
tag: 'item',
|
|
283
|
-
attrs:
|
|
284
|
-
action,
|
|
285
|
-
jid
|
|
286
|
-
}
|
|
316
|
+
attrs: itemAttrs
|
|
287
317
|
}
|
|
288
318
|
]
|
|
289
319
|
});
|
|
290
320
|
};
|
|
291
321
|
const getBusinessProfile = async (jid) => {
|
|
292
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
293
322
|
const results = await query({
|
|
294
323
|
tag: 'iq',
|
|
295
324
|
attrs: {
|
|
@@ -297,38 +326,42 @@ const makeChatsSocket = (config) => {
|
|
|
297
326
|
xmlns: 'w:biz',
|
|
298
327
|
type: 'get'
|
|
299
328
|
},
|
|
300
|
-
content: [
|
|
329
|
+
content: [
|
|
330
|
+
{
|
|
301
331
|
tag: 'business_profile',
|
|
302
332
|
attrs: { v: '244' },
|
|
303
|
-
content: [
|
|
333
|
+
content: [
|
|
334
|
+
{
|
|
304
335
|
tag: 'profile',
|
|
305
336
|
attrs: { jid }
|
|
306
|
-
}
|
|
307
|
-
|
|
337
|
+
}
|
|
338
|
+
]
|
|
339
|
+
}
|
|
340
|
+
]
|
|
308
341
|
});
|
|
309
|
-
const profileNode = (0,
|
|
310
|
-
const profiles = (0,
|
|
342
|
+
const profileNode = (0, index_js_5.getBinaryNodeChild)(results, 'business_profile');
|
|
343
|
+
const profiles = (0, index_js_5.getBinaryNodeChild)(profileNode, 'profile');
|
|
311
344
|
if (profiles) {
|
|
312
|
-
const address = (0,
|
|
313
|
-
const description = (0,
|
|
314
|
-
const website = (0,
|
|
315
|
-
const email = (0,
|
|
316
|
-
const category = (0,
|
|
317
|
-
const businessHours = (0,
|
|
345
|
+
const address = (0, index_js_5.getBinaryNodeChild)(profiles, 'address');
|
|
346
|
+
const description = (0, index_js_5.getBinaryNodeChild)(profiles, 'description');
|
|
347
|
+
const website = (0, index_js_5.getBinaryNodeChild)(profiles, 'website');
|
|
348
|
+
const email = (0, index_js_5.getBinaryNodeChild)(profiles, 'email');
|
|
349
|
+
const category = (0, index_js_5.getBinaryNodeChild)((0, index_js_5.getBinaryNodeChild)(profiles, 'categories'), 'category');
|
|
350
|
+
const businessHours = (0, index_js_5.getBinaryNodeChild)(profiles, 'business_hours');
|
|
318
351
|
const businessHoursConfig = businessHours
|
|
319
|
-
? (0,
|
|
352
|
+
? (0, index_js_5.getBinaryNodeChildren)(businessHours, 'business_hours_config')
|
|
320
353
|
: undefined;
|
|
321
|
-
const websiteStr =
|
|
354
|
+
const websiteStr = website?.content?.toString();
|
|
322
355
|
return {
|
|
323
|
-
wid:
|
|
324
|
-
address:
|
|
325
|
-
description:
|
|
356
|
+
wid: profiles.attrs?.jid,
|
|
357
|
+
address: address?.content?.toString(),
|
|
358
|
+
description: description?.content?.toString() || '',
|
|
326
359
|
website: websiteStr ? [websiteStr] : [],
|
|
327
|
-
email:
|
|
328
|
-
category:
|
|
329
|
-
|
|
330
|
-
timezone:
|
|
331
|
-
|
|
360
|
+
email: email?.content?.toString(),
|
|
361
|
+
category: category?.content?.toString(),
|
|
362
|
+
business_hours: {
|
|
363
|
+
timezone: businessHours?.attrs?.timezone,
|
|
364
|
+
business_config: businessHoursConfig?.map(({ attrs }) => attrs)
|
|
332
365
|
}
|
|
333
366
|
};
|
|
334
367
|
}
|
|
@@ -338,17 +371,17 @@ const makeChatsSocket = (config) => {
|
|
|
338
371
|
await sendNode({
|
|
339
372
|
tag: 'iq',
|
|
340
373
|
attrs: {
|
|
341
|
-
to:
|
|
374
|
+
to: index_js_5.S_WHATSAPP_NET,
|
|
342
375
|
type: 'set',
|
|
343
376
|
xmlns: 'urn:xmpp:whatsapp:dirty',
|
|
344
|
-
id: generateMessageTag()
|
|
377
|
+
id: generateMessageTag()
|
|
345
378
|
},
|
|
346
379
|
content: [
|
|
347
380
|
{
|
|
348
381
|
tag: 'clean',
|
|
349
382
|
attrs: {
|
|
350
383
|
type,
|
|
351
|
-
...(fromTimestamp ? { timestamp: fromTimestamp.toString() } : null)
|
|
384
|
+
...(fromTimestamp ? { timestamp: fromTimestamp.toString() } : null)
|
|
352
385
|
}
|
|
353
386
|
}
|
|
354
387
|
]
|
|
@@ -357,17 +390,31 @@ const makeChatsSocket = (config) => {
|
|
|
357
390
|
const newAppStateChunkHandler = (isInitialSync) => {
|
|
358
391
|
return {
|
|
359
392
|
onMutation(mutation) {
|
|
360
|
-
(0,
|
|
393
|
+
(0, index_js_4.processSyncAction)(mutation, ev, authState.creds.me, isInitialSync ? { accountSettings: authState.creds.accountSettings } : undefined, logger);
|
|
361
394
|
}
|
|
362
395
|
};
|
|
363
396
|
};
|
|
364
397
|
const resyncAppState = ev.createBufferedFunction(async (collections, isInitialSync) => {
|
|
398
|
+
const appStateSyncKeyCache = new Map();
|
|
399
|
+
const getCachedAppStateSyncKey = async (keyId) => {
|
|
400
|
+
if (appStateSyncKeyCache.has(keyId)) {
|
|
401
|
+
return appStateSyncKeyCache.get(keyId) ?? undefined;
|
|
402
|
+
}
|
|
403
|
+
const key = await getAppStateSyncKey(keyId);
|
|
404
|
+
appStateSyncKeyCache.set(keyId, key ?? null);
|
|
405
|
+
return key;
|
|
406
|
+
};
|
|
407
|
+
// we use this to determine which events to fire
|
|
408
|
+
// otherwise when we resync from scratch -- all notifications will fire
|
|
365
409
|
const initialVersionMap = {};
|
|
366
410
|
const globalMutationMap = {};
|
|
367
411
|
await authState.keys.transaction(async () => {
|
|
368
|
-
var _a;
|
|
369
412
|
const collectionsToHandle = new Set(collections);
|
|
413
|
+
// in case something goes wrong -- ensure we don't enter a loop that cannot be exited from
|
|
370
414
|
const attemptsMap = {};
|
|
415
|
+
// keep executing till all collections are done
|
|
416
|
+
// sometimes a single patch request will not return all the patches (God knows why)
|
|
417
|
+
// so we fetch till they're all done (this is determined by the "has_more_patches" flag)
|
|
371
418
|
while (collectionsToHandle.size) {
|
|
372
419
|
const states = {};
|
|
373
420
|
const nodes = [];
|
|
@@ -380,7 +427,7 @@ const makeChatsSocket = (config) => {
|
|
|
380
427
|
}
|
|
381
428
|
}
|
|
382
429
|
else {
|
|
383
|
-
state = (0,
|
|
430
|
+
state = (0, index_js_4.newLTHashState)();
|
|
384
431
|
}
|
|
385
432
|
states[name] = state;
|
|
386
433
|
logger.info(`resyncing ${name} from v${state.version}`);
|
|
@@ -389,14 +436,15 @@ const makeChatsSocket = (config) => {
|
|
|
389
436
|
attrs: {
|
|
390
437
|
name,
|
|
391
438
|
version: state.version.toString(),
|
|
392
|
-
|
|
439
|
+
// return snapshot if being synced from scratch
|
|
440
|
+
return_snapshot: (!state.version).toString()
|
|
393
441
|
}
|
|
394
442
|
});
|
|
395
443
|
}
|
|
396
444
|
const result = await query({
|
|
397
445
|
tag: 'iq',
|
|
398
446
|
attrs: {
|
|
399
|
-
to:
|
|
447
|
+
to: index_js_5.S_WHATSAPP_NET,
|
|
400
448
|
xmlns: 'w:sync:app:state',
|
|
401
449
|
type: 'set'
|
|
402
450
|
},
|
|
@@ -408,20 +456,22 @@ const makeChatsSocket = (config) => {
|
|
|
408
456
|
}
|
|
409
457
|
]
|
|
410
458
|
});
|
|
411
|
-
|
|
459
|
+
// extract from binary node
|
|
460
|
+
const decoded = await (0, index_js_4.extractSyncdPatches)(result, config?.options);
|
|
412
461
|
for (const key in decoded) {
|
|
413
462
|
const name = key;
|
|
414
463
|
const { patches, hasMorePatches, snapshot } = decoded[name];
|
|
415
464
|
try {
|
|
416
465
|
if (snapshot) {
|
|
417
|
-
const { state: newState, mutationMap } = await (0,
|
|
466
|
+
const { state: newState, mutationMap } = await (0, index_js_4.decodeSyncdSnapshot)(name, snapshot, getCachedAppStateSyncKey, initialVersionMap[name], appStateMacVerification.snapshot);
|
|
418
467
|
states[name] = newState;
|
|
419
468
|
Object.assign(globalMutationMap, mutationMap);
|
|
420
469
|
logger.info(`restored state of ${name} from snapshot to v${newState.version} with mutations`);
|
|
421
470
|
await authState.keys.set({ 'app-state-sync-version': { [name]: newState } });
|
|
422
471
|
}
|
|
472
|
+
// only process if there are syncd patches
|
|
423
473
|
if (patches.length) {
|
|
424
|
-
const { state: newState, mutationMap } = await (0,
|
|
474
|
+
const { state: newState, mutationMap } = await (0, index_js_4.decodePatches)(name, patches, states[name], getCachedAppStateSyncKey, config.options, initialVersionMap[name], logger, appStateMacVerification.patch);
|
|
425
475
|
await authState.keys.set({ 'app-state-sync-version': { [name]: newState } });
|
|
426
476
|
logger.info(`synced ${name} to v${newState.version}`);
|
|
427
477
|
initialVersionMap[name] = newState.version;
|
|
@@ -431,60 +481,54 @@ const makeChatsSocket = (config) => {
|
|
|
431
481
|
logger.info(`${name} has more patches...`);
|
|
432
482
|
}
|
|
433
483
|
else {
|
|
484
|
+
// collection is done with sync
|
|
434
485
|
collectionsToHandle.delete(name);
|
|
435
486
|
}
|
|
436
487
|
}
|
|
437
488
|
catch (error) {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
489
|
+
// if retry attempts overshoot
|
|
490
|
+
// or key not found
|
|
491
|
+
const isIrrecoverableError = attemptsMap[name] >= MAX_SYNC_ATTEMPTS ||
|
|
492
|
+
error.output?.statusCode === 404 ||
|
|
493
|
+
error.name === 'TypeError';
|
|
441
494
|
logger.info({ name, error: error.stack }, `failed to sync state from version${isIrrecoverableError ? '' : ', removing and trying from scratch'}`);
|
|
442
495
|
await authState.keys.set({ 'app-state-sync-version': { [name]: null } });
|
|
496
|
+
// increment number of retries
|
|
443
497
|
attemptsMap[name] = (attemptsMap[name] || 0) + 1;
|
|
444
498
|
if (isIrrecoverableError) {
|
|
499
|
+
// stop retrying
|
|
445
500
|
collectionsToHandle.delete(name);
|
|
446
501
|
}
|
|
447
502
|
}
|
|
448
503
|
}
|
|
449
504
|
}
|
|
450
|
-
});
|
|
505
|
+
}, authState?.creds?.me?.id || 'resync-app-state');
|
|
451
506
|
const { onMutation } = newAppStateChunkHandler(isInitialSync);
|
|
452
507
|
for (const key in globalMutationMap) {
|
|
453
508
|
onMutation(globalMutationMap[key]);
|
|
454
509
|
}
|
|
455
510
|
});
|
|
511
|
+
/**
|
|
512
|
+
* fetch the profile picture of a user/group
|
|
513
|
+
* type = "preview" for a low res picture
|
|
514
|
+
* type = "image for the high res picture"
|
|
515
|
+
*/
|
|
456
516
|
const profilePictureUrl = async (jid, type = 'preview', timeoutMs) => {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
const child = (0, WABinary_1.getBinaryNodeChild)(result, 'picture');
|
|
473
|
-
return (_a = child === null || child === void 0 ? void 0 : child.attrs) === null || _a === void 0 ? void 0 : _a.url;
|
|
474
|
-
} catch (error) {
|
|
475
|
-
if (error.message?.includes('item-not-found') ||
|
|
476
|
-
error.output?.payload?.statusCode === 404 ||
|
|
477
|
-
error.statusCode === 404) {
|
|
478
|
-
logger.info(chalk.gray(`[INFO] Profile pic not found for ${jid}, using fallback`));
|
|
479
|
-
return {
|
|
480
|
-
eurl: undefined,
|
|
481
|
-
id: jid.split('@')[0],
|
|
482
|
-
status: null,
|
|
483
|
-
img: null
|
|
484
|
-
};
|
|
485
|
-
}
|
|
486
|
-
throw error;
|
|
487
|
-
}
|
|
517
|
+
const baseContent = [{ tag: 'picture', attrs: { type, query: 'url' } }];
|
|
518
|
+
const tcTokenContent = await (0, tc_token_utils_js_1.buildTcTokenFromJid)({ authState, jid, baseContent });
|
|
519
|
+
jid = (0, index_js_5.jidNormalizedUser)(jid);
|
|
520
|
+
const result = await query({
|
|
521
|
+
tag: 'iq',
|
|
522
|
+
attrs: {
|
|
523
|
+
target: jid,
|
|
524
|
+
to: index_js_5.S_WHATSAPP_NET,
|
|
525
|
+
type: 'get',
|
|
526
|
+
xmlns: 'w:profile:picture'
|
|
527
|
+
},
|
|
528
|
+
content: tcTokenContent
|
|
529
|
+
}, timeoutMs);
|
|
530
|
+
const child = (0, index_js_5.getBinaryNodeChild)(result, 'picture');
|
|
531
|
+
return child?.attrs?.url;
|
|
488
532
|
};
|
|
489
533
|
const createCallLink = async (type, event, timeoutMs) => {
|
|
490
534
|
const result = await query({
|
|
@@ -501,17 +545,21 @@ const makeChatsSocket = (config) => {
|
|
|
501
545
|
}
|
|
502
546
|
]
|
|
503
547
|
}, timeoutMs);
|
|
504
|
-
const child = (0,
|
|
548
|
+
const child = (0, index_js_5.getBinaryNodeChild)(result, 'link_create');
|
|
505
549
|
return child?.attrs?.token;
|
|
506
550
|
};
|
|
507
551
|
const sendPresenceUpdate = async (type, toJid) => {
|
|
508
552
|
const me = authState.creds.me;
|
|
509
|
-
|
|
553
|
+
const isAvailableType = type === 'available';
|
|
554
|
+
if (isAvailableType || type === 'unavailable') {
|
|
510
555
|
if (!me.name) {
|
|
511
556
|
logger.warn('no name present, ignoring presence update request...');
|
|
512
557
|
return;
|
|
513
558
|
}
|
|
514
|
-
ev.emit('connection.update', { isOnline:
|
|
559
|
+
ev.emit('connection.update', { isOnline: isAvailableType });
|
|
560
|
+
if (isAvailableType) {
|
|
561
|
+
void sendUnifiedSession();
|
|
562
|
+
}
|
|
515
563
|
await sendNode({
|
|
516
564
|
tag: 'presence',
|
|
517
565
|
attrs: {
|
|
@@ -521,13 +569,13 @@ const makeChatsSocket = (config) => {
|
|
|
521
569
|
});
|
|
522
570
|
}
|
|
523
571
|
else {
|
|
524
|
-
const { server } = (0,
|
|
572
|
+
const { server } = (0, index_js_5.jidDecode)(toJid);
|
|
525
573
|
const isLid = server === 'lid';
|
|
526
574
|
await sendNode({
|
|
527
575
|
tag: 'chatstate',
|
|
528
576
|
attrs: {
|
|
529
577
|
from: isLid ? me.lid : me.id,
|
|
530
|
-
to: toJid
|
|
578
|
+
to: toJid
|
|
531
579
|
},
|
|
532
580
|
content: [
|
|
533
581
|
{
|
|
@@ -538,29 +586,27 @@ const makeChatsSocket = (config) => {
|
|
|
538
586
|
});
|
|
539
587
|
}
|
|
540
588
|
};
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
}));
|
|
589
|
+
/**
|
|
590
|
+
* @param toJid the jid to subscribe to
|
|
591
|
+
* @param tcToken token for subscription, use if present
|
|
592
|
+
*/
|
|
593
|
+
const presenceSubscribe = async (toJid) => {
|
|
594
|
+
const tcTokenContent = await (0, tc_token_utils_js_1.buildTcTokenFromJid)({ authState, jid: toJid });
|
|
595
|
+
return sendNode({
|
|
596
|
+
tag: 'presence',
|
|
597
|
+
attrs: {
|
|
598
|
+
to: toJid,
|
|
599
|
+
id: generateMessageTag(),
|
|
600
|
+
type: 'subscribe'
|
|
601
|
+
},
|
|
602
|
+
content: tcTokenContent
|
|
603
|
+
});
|
|
604
|
+
};
|
|
558
605
|
const handlePresenceUpdate = ({ tag, attrs, content }) => {
|
|
559
|
-
var _a;
|
|
560
606
|
let presence;
|
|
561
607
|
const jid = attrs.from;
|
|
562
608
|
const participant = attrs.participant || attrs.from;
|
|
563
|
-
if (shouldIgnoreJid(jid) && jid
|
|
609
|
+
if (shouldIgnoreJid(jid) && jid !== index_js_5.S_WHATSAPP_NET) {
|
|
564
610
|
return;
|
|
565
611
|
}
|
|
566
612
|
if (tag === 'presence') {
|
|
@@ -575,7 +621,7 @@ const makeChatsSocket = (config) => {
|
|
|
575
621
|
if (type === 'paused') {
|
|
576
622
|
type = 'available';
|
|
577
623
|
}
|
|
578
|
-
if (
|
|
624
|
+
if (firstChild.attrs?.media === 'audio') {
|
|
579
625
|
type = 'recording';
|
|
580
626
|
}
|
|
581
627
|
presence = { lastKnownPresence: type };
|
|
@@ -595,18 +641,18 @@ const makeChatsSocket = (config) => {
|
|
|
595
641
|
}
|
|
596
642
|
let initial;
|
|
597
643
|
let encodeResult;
|
|
598
|
-
await
|
|
644
|
+
await appStatePatchMutex.mutex(async () => {
|
|
599
645
|
await authState.keys.transaction(async () => {
|
|
600
646
|
logger.debug({ patch: patchCreate }, 'applying app patch');
|
|
601
647
|
await resyncAppState([name], false);
|
|
602
648
|
const { [name]: currentSyncVersion } = await authState.keys.get('app-state-sync-version', [name]);
|
|
603
|
-
initial = currentSyncVersion || (0,
|
|
604
|
-
encodeResult = await (0,
|
|
649
|
+
initial = currentSyncVersion || (0, index_js_4.newLTHashState)();
|
|
650
|
+
encodeResult = await (0, index_js_4.encodeSyncdPatch)(patchCreate, myAppStateKeyId, initial, getAppStateSyncKey);
|
|
605
651
|
const { patch, state } = encodeResult;
|
|
606
652
|
const node = {
|
|
607
653
|
tag: 'iq',
|
|
608
654
|
attrs: {
|
|
609
|
-
to:
|
|
655
|
+
to: index_js_5.S_WHATSAPP_NET,
|
|
610
656
|
type: 'set',
|
|
611
657
|
xmlns: 'w:sync:app:state'
|
|
612
658
|
},
|
|
@@ -620,13 +666,13 @@ const makeChatsSocket = (config) => {
|
|
|
620
666
|
attrs: {
|
|
621
667
|
name,
|
|
622
668
|
version: (state.version - 1).toString(),
|
|
623
|
-
|
|
669
|
+
return_snapshot: 'false'
|
|
624
670
|
},
|
|
625
671
|
content: [
|
|
626
672
|
{
|
|
627
673
|
tag: 'patch',
|
|
628
674
|
attrs: {},
|
|
629
|
-
content:
|
|
675
|
+
content: index_js_1.proto.SyncdPatch.encode(patch).finish()
|
|
630
676
|
}
|
|
631
677
|
]
|
|
632
678
|
}
|
|
@@ -636,48 +682,69 @@ const makeChatsSocket = (config) => {
|
|
|
636
682
|
};
|
|
637
683
|
await query(node);
|
|
638
684
|
await authState.keys.set({ 'app-state-sync-version': { [name]: state } });
|
|
639
|
-
});
|
|
685
|
+
}, authState?.creds?.me?.id || 'app-patch');
|
|
640
686
|
});
|
|
641
687
|
if (config.emitOwnEvents) {
|
|
642
688
|
const { onMutation } = newAppStateChunkHandler(false);
|
|
643
|
-
const { mutationMap } = await (0,
|
|
689
|
+
const { mutationMap } = await (0, index_js_4.decodePatches)(name, [{ ...encodeResult.patch, version: { version: encodeResult.state.version } }], initial, getAppStateSyncKey, config.options, undefined, logger);
|
|
644
690
|
for (const key in mutationMap) {
|
|
645
691
|
onMutation(mutationMap[key]);
|
|
646
692
|
}
|
|
647
693
|
}
|
|
648
694
|
};
|
|
695
|
+
/** sending non-abt props may fix QR scan fail if server expects */
|
|
649
696
|
const fetchProps = async () => {
|
|
650
|
-
|
|
697
|
+
//TODO: implement both protocol 1 and protocol 2 prop fetching, specially for abKey for WM
|
|
651
698
|
const resultNode = await query({
|
|
652
699
|
tag: 'iq',
|
|
653
700
|
attrs: {
|
|
654
|
-
to:
|
|
701
|
+
to: index_js_5.S_WHATSAPP_NET,
|
|
655
702
|
xmlns: 'w',
|
|
656
|
-
type: 'get'
|
|
703
|
+
type: 'get'
|
|
657
704
|
},
|
|
658
705
|
content: [
|
|
659
|
-
{
|
|
706
|
+
{
|
|
707
|
+
tag: 'props',
|
|
708
|
+
attrs: {
|
|
660
709
|
protocol: '2',
|
|
661
|
-
hash:
|
|
662
|
-
}
|
|
710
|
+
hash: authState?.creds?.lastPropHash || ''
|
|
711
|
+
}
|
|
712
|
+
}
|
|
663
713
|
]
|
|
664
714
|
});
|
|
665
|
-
const propsNode = (0,
|
|
715
|
+
const propsNode = (0, index_js_5.getBinaryNodeChild)(resultNode, 'props');
|
|
666
716
|
let props = {};
|
|
667
717
|
if (propsNode) {
|
|
668
|
-
if (
|
|
669
|
-
|
|
718
|
+
if (propsNode.attrs?.hash) {
|
|
719
|
+
// on some clients, the hash is returning as undefined
|
|
720
|
+
authState.creds.lastPropHash = propsNode?.attrs?.hash;
|
|
670
721
|
ev.emit('creds.update', authState.creds);
|
|
671
722
|
}
|
|
672
|
-
props = (0,
|
|
723
|
+
props = (0, index_js_5.reduceBinaryNodeToDictionary)(propsNode, 'prop');
|
|
673
724
|
}
|
|
674
725
|
logger.debug('fetched props');
|
|
675
726
|
return props;
|
|
676
727
|
};
|
|
728
|
+
/**
|
|
729
|
+
* modify a chat -- mark unread, read etc.
|
|
730
|
+
* lastMessages must be sorted in reverse chronologically
|
|
731
|
+
* requires the last messages till the last message received; required for archive & unread
|
|
732
|
+
*/
|
|
677
733
|
const chatModify = (mod, jid) => {
|
|
678
|
-
const patch = (0,
|
|
734
|
+
const patch = (0, index_js_4.chatModificationToAppPatch)(mod, jid);
|
|
679
735
|
return appPatch(patch);
|
|
680
736
|
};
|
|
737
|
+
/**
|
|
738
|
+
* Enable/Disable link preview privacy, not related to baileys link preview generation
|
|
739
|
+
*/
|
|
740
|
+
const updateDisableLinkPreviewsPrivacy = (isPreviewsDisabled) => {
|
|
741
|
+
return chatModify({
|
|
742
|
+
disableLinkPreviews: { isPreviewsDisabled }
|
|
743
|
+
}, '');
|
|
744
|
+
};
|
|
745
|
+
/**
|
|
746
|
+
* Star or Unstar a message
|
|
747
|
+
*/
|
|
681
748
|
const star = (jid, messages, star) => {
|
|
682
749
|
return chatModify({
|
|
683
750
|
star: {
|
|
@@ -686,15 +753,35 @@ const makeChatsSocket = (config) => {
|
|
|
686
753
|
}
|
|
687
754
|
}, jid);
|
|
688
755
|
};
|
|
756
|
+
/**
|
|
757
|
+
* Add or Edit Contact
|
|
758
|
+
*/
|
|
689
759
|
const addOrEditContact = (jid, contact) => {
|
|
690
|
-
return chatModify({
|
|
760
|
+
return chatModify({
|
|
761
|
+
contact
|
|
762
|
+
}, jid);
|
|
691
763
|
};
|
|
764
|
+
/**
|
|
765
|
+
* Remove Contact
|
|
766
|
+
*/
|
|
692
767
|
const removeContact = (jid) => {
|
|
693
|
-
return chatModify({
|
|
768
|
+
return chatModify({
|
|
769
|
+
contact: null
|
|
770
|
+
}, jid);
|
|
694
771
|
};
|
|
772
|
+
/**
|
|
773
|
+
* Adds label
|
|
774
|
+
*/
|
|
695
775
|
const addLabel = (jid, labels) => {
|
|
696
|
-
return chatModify({
|
|
776
|
+
return chatModify({
|
|
777
|
+
addLabel: {
|
|
778
|
+
...labels
|
|
779
|
+
}
|
|
780
|
+
}, jid);
|
|
697
781
|
};
|
|
782
|
+
/**
|
|
783
|
+
* Adds label for the chats
|
|
784
|
+
*/
|
|
698
785
|
const addChatLabel = (jid, labelId) => {
|
|
699
786
|
return chatModify({
|
|
700
787
|
addChatLabel: {
|
|
@@ -702,6 +789,9 @@ const makeChatsSocket = (config) => {
|
|
|
702
789
|
}
|
|
703
790
|
}, jid);
|
|
704
791
|
};
|
|
792
|
+
/**
|
|
793
|
+
* Removes label for the chat
|
|
794
|
+
*/
|
|
705
795
|
const removeChatLabel = (jid, labelId) => {
|
|
706
796
|
return chatModify({
|
|
707
797
|
removeChatLabel: {
|
|
@@ -709,6 +799,9 @@ const makeChatsSocket = (config) => {
|
|
|
709
799
|
}
|
|
710
800
|
}, jid);
|
|
711
801
|
};
|
|
802
|
+
/**
|
|
803
|
+
* Adds label for the message
|
|
804
|
+
*/
|
|
712
805
|
const addMessageLabel = (jid, messageId, labelId) => {
|
|
713
806
|
return chatModify({
|
|
714
807
|
addMessageLabel: {
|
|
@@ -717,6 +810,9 @@ const makeChatsSocket = (config) => {
|
|
|
717
810
|
}
|
|
718
811
|
}, jid);
|
|
719
812
|
};
|
|
813
|
+
/**
|
|
814
|
+
* Removes label for the message
|
|
815
|
+
*/
|
|
720
816
|
const removeMessageLabel = (jid, messageId, labelId) => {
|
|
721
817
|
return chatModify({
|
|
722
818
|
removeMessageLabel: {
|
|
@@ -725,119 +821,149 @@ const makeChatsSocket = (config) => {
|
|
|
725
821
|
}
|
|
726
822
|
}, jid);
|
|
727
823
|
};
|
|
824
|
+
/**
|
|
825
|
+
* Add or Edit Quick Reply
|
|
826
|
+
*/
|
|
827
|
+
const addOrEditQuickReply = (quickReply) => {
|
|
828
|
+
return chatModify({
|
|
829
|
+
quickReply
|
|
830
|
+
}, '');
|
|
831
|
+
};
|
|
832
|
+
/**
|
|
833
|
+
* Remove Quick Reply
|
|
834
|
+
*/
|
|
835
|
+
const removeQuickReply = (timestamp) => {
|
|
836
|
+
return chatModify({
|
|
837
|
+
quickReply: { timestamp, deleted: true }
|
|
838
|
+
}, '');
|
|
839
|
+
};
|
|
840
|
+
/**
|
|
841
|
+
* queries need to be fired on connection open
|
|
842
|
+
* help ensure parity with WA Web
|
|
843
|
+
* */
|
|
728
844
|
const executeInitQueries = async () => {
|
|
729
|
-
await Promise.all([
|
|
730
|
-
fetchProps(),
|
|
731
|
-
fetchBlocklist(),
|
|
732
|
-
fetchPrivacySettings(),
|
|
733
|
-
]);
|
|
845
|
+
await Promise.all([fetchProps(), fetchBlocklist(), fetchPrivacySettings()]);
|
|
734
846
|
};
|
|
735
|
-
const canonicalizeUserJid = (jid) => {
|
|
736
|
-
if (!jid) {
|
|
737
|
-
return jid;
|
|
738
|
-
}
|
|
739
|
-
if ((0, WABinary_1.isLidUser)(jid)) {
|
|
740
|
-
return (0, WABinary_1.lidToJid)(jid);
|
|
741
|
-
}
|
|
742
|
-
return jid;
|
|
743
|
-
};
|
|
744
|
-
const extractStanzaId = (msg) => {
|
|
745
|
-
var _a, _b;
|
|
746
|
-
const topLevelStanzaId = (_a = msg.messageContextInfo) === null || _a === void 0 ? void 0 : _a.stanzaId;
|
|
747
|
-
if (topLevelStanzaId) {
|
|
748
|
-
return topLevelStanzaId;
|
|
749
|
-
}
|
|
750
|
-
const messageContextStanzaId = (_b = msg.message) === null || _b === void 0 ? void 0 : _b.messageContextInfo;
|
|
751
|
-
if (messageContextStanzaId === null || messageContextStanzaId === void 0 ? void 0 : messageContextStanzaId.stanzaId) {
|
|
752
|
-
return messageContextStanzaId.stanzaId;
|
|
753
|
-
}
|
|
754
|
-
const normalizedContent = (0, Utils_1.normalizeMessageContent)(msg.message);
|
|
755
|
-
const contentType = normalizedContent ? (0, Utils_1.getContentType)(normalizedContent) : undefined;
|
|
756
|
-
const contentContextStanzaId = contentType
|
|
757
|
-
? normalizedContent[contentType].contextInfo && normalizedContent[contentType].contextInfo.stanzaId
|
|
758
|
-
: undefined;
|
|
759
|
-
return contentContextStanzaId;
|
|
760
|
-
};
|
|
761
|
-
const buildMessageDedupKeys = (msg) => {
|
|
762
|
-
const remoteJid = canonicalizeUserJid(msg.key.remoteJid);
|
|
763
|
-
const participant = canonicalizeUserJid(msg.key.participant);
|
|
764
|
-
const stanzaId = extractStanzaId(msg);
|
|
765
|
-
const primaryKey = [remoteJid, participant, msg.key.id, msg.key.fromMe ? '1' : '0', stanzaId || ''].join('|');
|
|
766
|
-
const keys = [primaryKey];
|
|
767
|
-
// fallback alias key to collapse LID->PN duplicate deliveries for the same incoming user message ID
|
|
768
|
-
if (!msg.key.fromMe && ((0, WABinary_1.isJidUser)(msg.key.remoteJid) || (0, WABinary_1.isLidUser)(msg.key.remoteJid))) {
|
|
769
|
-
keys.push(`incoming-user-id|${msg.key.id}|${stanzaId || ''}`);
|
|
770
|
-
}
|
|
771
|
-
return keys;
|
|
772
|
-
};
|
|
773
|
-
const getDedupState = (msg) => msg.messageStubType === WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT
|
|
774
|
-
? 'ciphertext'
|
|
775
|
-
: 'final';
|
|
776
847
|
const upsertMessage = ev.createBufferedFunction(async (msg, type) => {
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
848
|
+
// ── Auto-inject isAdmin, isBotAdmin, metadata ─────────────────────────
|
|
849
|
+
try {
|
|
850
|
+
const remoteJid = msg.key?.remoteJid || '';
|
|
851
|
+
const isGroup = remoteJid.endsWith('@g.us');
|
|
852
|
+
if (isGroup) {
|
|
853
|
+
const _normalizeJid = (jid) => {
|
|
854
|
+
if (!jid)
|
|
855
|
+
return null;
|
|
856
|
+
try {
|
|
857
|
+
return (0, index_js_5.jidNormalizedUser)(jid).split('@')[0];
|
|
858
|
+
}
|
|
859
|
+
catch {
|
|
860
|
+
return String(jid).split('@')[0];
|
|
861
|
+
}
|
|
862
|
+
};
|
|
863
|
+
// Fetch metadata (pakai cache jika tersedia)
|
|
864
|
+
let meta = null;
|
|
865
|
+
try {
|
|
866
|
+
meta = await sock.groupMetadata(remoteJid);
|
|
867
|
+
}
|
|
868
|
+
catch { }
|
|
869
|
+
if (meta && Array.isArray(meta.participants)) {
|
|
870
|
+
msg.metadata = meta;
|
|
871
|
+
const botJid = authState.creds?.me?.id;
|
|
872
|
+
const senderJid = msg.key.fromMe
|
|
873
|
+
? authState.creds?.me?.id
|
|
874
|
+
: (msg.key.participant || remoteJid);
|
|
875
|
+
const senderNorm = _normalizeJid(senderJid);
|
|
876
|
+
const botNorm = _normalizeJid(botJid);
|
|
877
|
+
// isAdmin
|
|
878
|
+
msg.isAdmin = meta.participants.some(p => {
|
|
879
|
+
const pid = _normalizeJid(p.jid || p.id || p.lid);
|
|
880
|
+
return pid === senderNorm && (p.admin === 'admin' || p.admin === 'superadmin');
|
|
881
|
+
});
|
|
882
|
+
// isBotAdmin: via m.isBotAdmin jika sudah di-set
|
|
883
|
+
let isBotAdmin = typeof msg.isBotAdmin === 'boolean' ? msg.isBotAdmin : false;
|
|
884
|
+
// fallback via owner
|
|
885
|
+
if (!isBotAdmin) {
|
|
886
|
+
const owners = [meta.owner, meta.subjectOwner, meta.ownerPn]
|
|
887
|
+
.filter(Boolean).map(_normalizeJid);
|
|
888
|
+
if (owners.includes(botNorm))
|
|
889
|
+
isBotAdmin = true;
|
|
890
|
+
}
|
|
891
|
+
// fallback via participants
|
|
892
|
+
if (!isBotAdmin) {
|
|
893
|
+
isBotAdmin = meta.participants.some(p => {
|
|
894
|
+
const pid = _normalizeJid(p.jid || p.id || p.lid);
|
|
895
|
+
return pid === botNorm && (p.admin === 'admin' || p.admin === 'superadmin');
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
msg.isBotAdmin = isBotAdmin;
|
|
899
|
+
}
|
|
900
|
+
else {
|
|
901
|
+
msg.metadata = {};
|
|
902
|
+
msg.isAdmin = false;
|
|
903
|
+
msg.isBotAdmin = false;
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
else {
|
|
907
|
+
msg.metadata = {};
|
|
908
|
+
msg.isAdmin = false;
|
|
909
|
+
msg.isBotAdmin = false;
|
|
910
|
+
}
|
|
786
911
|
}
|
|
912
|
+
catch { }
|
|
913
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
787
914
|
ev.emit('messages.upsert', { messages: [msg], type });
|
|
788
915
|
if (!!msg.pushName) {
|
|
789
|
-
let jid = msg.key.fromMe ? authState.creds.me.id :
|
|
790
|
-
jid = (0,
|
|
916
|
+
let jid = msg.key.fromMe ? authState.creds.me.id : msg.key.participant || msg.key.remoteJid;
|
|
917
|
+
jid = (0, index_js_5.jidNormalizedUser)(jid);
|
|
791
918
|
if (!msg.key.fromMe) {
|
|
792
919
|
ev.emit('contacts.update', [{ id: jid, notify: msg.pushName, verifiedName: msg.verifiedBizName }]);
|
|
793
920
|
}
|
|
794
|
-
|
|
921
|
+
// update our pushname too
|
|
922
|
+
if (msg.key.fromMe && msg.pushName && authState.creds.me?.name !== msg.pushName) {
|
|
795
923
|
ev.emit('creds.update', { me: { ...authState.creds.me, name: msg.pushName } });
|
|
796
924
|
}
|
|
797
925
|
}
|
|
798
|
-
const historyMsg = (0,
|
|
926
|
+
const historyMsg = (0, index_js_4.getHistoryMsg)(msg.message);
|
|
799
927
|
const shouldProcessHistoryMsg = historyMsg
|
|
800
|
-
?
|
|
801
|
-
|
|
928
|
+
? shouldSyncHistoryMessage(historyMsg) &&
|
|
929
|
+
index_js_2.PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType)
|
|
802
930
|
: false;
|
|
803
|
-
|
|
931
|
+
// State machine: decide on sync and flush
|
|
932
|
+
if (historyMsg && syncState === State_js_1.SyncState.AwaitingInitialSync) {
|
|
804
933
|
if (awaitingSyncTimeout) {
|
|
805
934
|
clearTimeout(awaitingSyncTimeout);
|
|
806
935
|
awaitingSyncTimeout = undefined;
|
|
807
936
|
}
|
|
808
937
|
if (shouldProcessHistoryMsg) {
|
|
809
|
-
syncState = SyncState.Syncing;
|
|
938
|
+
syncState = State_js_1.SyncState.Syncing;
|
|
810
939
|
logger.info('Transitioned to Syncing state');
|
|
811
|
-
|
|
812
|
-
|
|
940
|
+
// Let doAppStateSync handle the final flush after it's done
|
|
941
|
+
}
|
|
942
|
+
else {
|
|
943
|
+
syncState = State_js_1.SyncState.Online;
|
|
813
944
|
logger.info('History sync skipped, transitioning to Online state and flushing buffer');
|
|
814
945
|
ev.flush();
|
|
815
946
|
}
|
|
816
947
|
}
|
|
817
948
|
const doAppStateSync = async () => {
|
|
818
|
-
if (syncState === SyncState.Syncing) {
|
|
949
|
+
if (syncState === State_js_1.SyncState.Syncing) {
|
|
819
950
|
logger.info('Doing app state sync');
|
|
820
|
-
await resyncAppState(
|
|
821
|
-
|
|
951
|
+
await resyncAppState(index_js_3.ALL_WA_PATCH_NAMES, true);
|
|
952
|
+
// Sync is complete, go online and flush everything
|
|
953
|
+
syncState = State_js_1.SyncState.Online;
|
|
822
954
|
logger.info('App state sync complete, transitioning to Online state and flushing buffer');
|
|
823
955
|
ev.flush();
|
|
824
956
|
const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1;
|
|
825
957
|
ev.emit('creds.update', { accountSyncCounter });
|
|
826
958
|
}
|
|
827
959
|
};
|
|
828
|
-
if (historyMsg && !authState.creds.myAppStateKeyId) {
|
|
829
|
-
logger.warn('skipping app state sync, as myAppStateKeyId is not set');
|
|
830
|
-
pendingAppStateSync = true;
|
|
831
|
-
}
|
|
832
960
|
await Promise.all([
|
|
833
961
|
(async () => {
|
|
834
|
-
if (
|
|
835
|
-
&& authState.creds.myAppStateKeyId) {
|
|
836
|
-
pendingAppStateSync = false;
|
|
962
|
+
if (shouldProcessHistoryMsg) {
|
|
837
963
|
await doAppStateSync();
|
|
838
964
|
}
|
|
839
965
|
})(),
|
|
840
|
-
(0,
|
|
966
|
+
(0, process_message_js_1.default)(msg, {
|
|
841
967
|
signalRepository,
|
|
842
968
|
shouldProcessHistoryMsg,
|
|
843
969
|
placeholderResendCache,
|
|
@@ -846,22 +972,19 @@ const makeChatsSocket = (config) => {
|
|
|
846
972
|
keyStore: authState.keys,
|
|
847
973
|
logger,
|
|
848
974
|
options: config.options,
|
|
849
|
-
getMessage
|
|
975
|
+
getMessage
|
|
850
976
|
})
|
|
851
977
|
]);
|
|
852
|
-
|
|
853
|
-
|
|
978
|
+
// If the app state key arrives and we are waiting to sync, trigger the sync now.
|
|
979
|
+
if (msg.message?.protocolMessage?.appStateSyncKeyShare && syncState === State_js_1.SyncState.Syncing) {
|
|
980
|
+
logger.info('App state sync key arrived, triggering app state sync');
|
|
854
981
|
await doAppStateSync();
|
|
855
|
-
pendingAppStateSync = false;
|
|
856
|
-
}
|
|
857
|
-
for (const key of dedupKeys) {
|
|
858
|
-
receivedMessageDedupCache.set(key, dedupState);
|
|
859
982
|
}
|
|
860
983
|
});
|
|
861
984
|
ws.on('CB:presence', handlePresenceUpdate);
|
|
862
985
|
ws.on('CB:chatstate', handlePresenceUpdate);
|
|
863
986
|
ws.on('CB:ib,,dirty', async (node) => {
|
|
864
|
-
const { attrs } = (0,
|
|
987
|
+
const { attrs } = (0, index_js_5.getBinaryNodeChild)(node, 'dirty');
|
|
865
988
|
const type = attrs.type;
|
|
866
989
|
switch (type) {
|
|
867
990
|
case 'account_sync':
|
|
@@ -875,6 +998,7 @@ const makeChatsSocket = (config) => {
|
|
|
875
998
|
}
|
|
876
999
|
break;
|
|
877
1000
|
case 'groups':
|
|
1001
|
+
// handled in groups.ts
|
|
878
1002
|
break;
|
|
879
1003
|
default:
|
|
880
1004
|
logger.info({ node }, 'received unknown sync');
|
|
@@ -882,34 +1006,24 @@ const makeChatsSocket = (config) => {
|
|
|
882
1006
|
}
|
|
883
1007
|
});
|
|
884
1008
|
ev.on('connection.update', ({ connection, receivedPendingNotifications }) => {
|
|
885
|
-
var _a;
|
|
886
1009
|
if (connection === 'open') {
|
|
887
1010
|
if (fireInitQueries) {
|
|
888
|
-
executeInitQueries()
|
|
889
|
-
.catch(error => onUnexpectedError(error, 'init queries'));
|
|
1011
|
+
executeInitQueries().catch(error => onUnexpectedError(error, 'init queries'));
|
|
890
1012
|
}
|
|
891
|
-
sendPresenceUpdate(markOnlineOnConnect ? 'available' : 'unavailable')
|
|
892
|
-
.catch(error => onUnexpectedError(error, 'presence update requests'));
|
|
893
|
-
}
|
|
894
|
-
if (receivedPendingNotifications &&
|
|
895
|
-
!((_a = authState.creds) === null || _a === void 0 ? void 0 : _a.myAppStateKeyId)) {
|
|
896
|
-
ev.buffer();
|
|
897
|
-
needToFlushWithAppStateSync = true;
|
|
1013
|
+
sendPresenceUpdate(markOnlineOnConnect ? 'available' : 'unavailable').catch(error => onUnexpectedError(error, 'presence update requests'));
|
|
898
1014
|
}
|
|
899
|
-
if (!receivedPendingNotifications || syncState !== SyncState.Connecting) {
|
|
1015
|
+
if (!receivedPendingNotifications || syncState !== State_js_1.SyncState.Connecting) {
|
|
900
1016
|
return;
|
|
901
1017
|
}
|
|
902
|
-
syncState = SyncState.AwaitingInitialSync;
|
|
1018
|
+
syncState = State_js_1.SyncState.AwaitingInitialSync;
|
|
903
1019
|
logger.info('Connection is now AwaitingInitialSync, buffering events');
|
|
904
1020
|
ev.buffer();
|
|
905
|
-
const willSyncHistory = shouldSyncHistoryMessage(
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
})
|
|
909
|
-
);
|
|
1021
|
+
const willSyncHistory = shouldSyncHistoryMessage(index_js_1.proto.Message.HistorySyncNotification.create({
|
|
1022
|
+
syncType: index_js_1.proto.HistorySync.HistorySyncType.RECENT
|
|
1023
|
+
}));
|
|
910
1024
|
if (!willSyncHistory) {
|
|
911
1025
|
logger.info('History sync is disabled by config, not waiting for notification. Transitioning to Online.');
|
|
912
|
-
syncState = SyncState.Online;
|
|
1026
|
+
syncState = State_js_1.SyncState.Online;
|
|
913
1027
|
setTimeout(() => ev.flush(), 0);
|
|
914
1028
|
return;
|
|
915
1029
|
}
|
|
@@ -918,28 +1032,85 @@ const makeChatsSocket = (config) => {
|
|
|
918
1032
|
clearTimeout(awaitingSyncTimeout);
|
|
919
1033
|
}
|
|
920
1034
|
awaitingSyncTimeout = setTimeout(() => {
|
|
921
|
-
if (syncState === SyncState.AwaitingInitialSync) {
|
|
1035
|
+
if (syncState === State_js_1.SyncState.AwaitingInitialSync) {
|
|
1036
|
+
// TODO: investigate
|
|
922
1037
|
logger.warn('Timeout in AwaitingInitialSync, forcing state to Online and flushing buffer');
|
|
923
|
-
syncState = SyncState.Online;
|
|
1038
|
+
syncState = State_js_1.SyncState.Online;
|
|
924
1039
|
ev.flush();
|
|
925
1040
|
}
|
|
926
1041
|
}, 20000);
|
|
927
1042
|
});
|
|
1043
|
+
ev.on('lid-mapping.update', async ({ lid, pn }) => {
|
|
1044
|
+
try {
|
|
1045
|
+
await signalRepository.lidMapping.storeLIDPNMappings([{ lid, pn }]);
|
|
1046
|
+
}
|
|
1047
|
+
catch (error) {
|
|
1048
|
+
logger.warn({ lid, pn, error }, 'Failed to store LID-PN mapping');
|
|
1049
|
+
}
|
|
1050
|
+
});
|
|
1051
|
+
ev.on('groups.upsert', async (groups) => {
|
|
1052
|
+
try {
|
|
1053
|
+
const mappings = [];
|
|
1054
|
+
for (const group of groups) {
|
|
1055
|
+
for (const p of group.participants || []) {
|
|
1056
|
+
const lidJid = p.id?.endsWith('@lid') ? p.id : p.lid;
|
|
1057
|
+
const pnJid = p.phoneNumber?.endsWith('@s.whatsapp.net')
|
|
1058
|
+
? p.phoneNumber
|
|
1059
|
+
: p.id?.endsWith('@s.whatsapp.net') ? p.id : undefined;
|
|
1060
|
+
if (lidJid && pnJid) {
|
|
1061
|
+
mappings.push({ lid: lidJid, pn: pnJid });
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
if (mappings.length > 0) {
|
|
1066
|
+
await signalRepository.lidMapping.storeLIDPNMappings(mappings);
|
|
1067
|
+
logger.debug({ count: mappings.length }, 'groups.upsert: stored LID-PN mappings from participants');
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
catch (error) {
|
|
1071
|
+
logger.warn({ error }, 'groups.upsert: failed to store LID-PN mappings');
|
|
1072
|
+
}
|
|
1073
|
+
});
|
|
1074
|
+
ev.on('groups.update', async (updates) => {
|
|
1075
|
+
try {
|
|
1076
|
+
const mappings = [];
|
|
1077
|
+
for (const update of updates) {
|
|
1078
|
+
for (const p of update.participants || []) {
|
|
1079
|
+
const lidJid = p.id?.endsWith('@lid') ? p.id : p.lid;
|
|
1080
|
+
const pnJid = p.phoneNumber?.endsWith('@s.whatsapp.net')
|
|
1081
|
+
? p.phoneNumber
|
|
1082
|
+
: p.id?.endsWith('@s.whatsapp.net') ? p.id : undefined;
|
|
1083
|
+
if (lidJid && pnJid) {
|
|
1084
|
+
mappings.push({ lid: lidJid, pn: pnJid });
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
if (mappings.length > 0) {
|
|
1089
|
+
await signalRepository.lidMapping.storeLIDPNMappings(mappings);
|
|
1090
|
+
logger.debug({ count: mappings.length }, 'groups.update: stored LID-PN mappings from participants');
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
catch (error) {
|
|
1094
|
+
logger.warn({ error }, 'groups.update: failed to store LID-PN mappings');
|
|
1095
|
+
}
|
|
1096
|
+
});
|
|
928
1097
|
return {
|
|
929
1098
|
...sock,
|
|
930
1099
|
createCallLink,
|
|
931
1100
|
getBotListV2,
|
|
932
|
-
|
|
1101
|
+
messageMutex,
|
|
1102
|
+
receiptMutex,
|
|
1103
|
+
appStatePatchMutex,
|
|
1104
|
+
notificationMutex,
|
|
933
1105
|
fetchPrivacySettings,
|
|
934
1106
|
upsertMessage,
|
|
935
1107
|
appPatch,
|
|
936
1108
|
sendPresenceUpdate,
|
|
937
1109
|
presenceSubscribe,
|
|
938
1110
|
profilePictureUrl,
|
|
939
|
-
onWhatsApp,
|
|
940
1111
|
fetchBlocklist,
|
|
941
|
-
fetchDisappearingDuration,
|
|
942
1112
|
fetchStatus,
|
|
1113
|
+
fetchDisappearingDuration,
|
|
943
1114
|
updateProfilePicture,
|
|
944
1115
|
removeProfilePicture,
|
|
945
1116
|
updateProfileStatus,
|
|
@@ -966,7 +1137,19 @@ const makeChatsSocket = (config) => {
|
|
|
966
1137
|
removeChatLabel,
|
|
967
1138
|
addMessageLabel,
|
|
968
1139
|
removeMessageLabel,
|
|
969
|
-
star
|
|
1140
|
+
star,
|
|
1141
|
+
addOrEditQuickReply,
|
|
1142
|
+
removeQuickReply,
|
|
1143
|
+
clearMessage: (jid, key, timeStamp) => {
|
|
1144
|
+
return chatModify({
|
|
1145
|
+
delete: true,
|
|
1146
|
+
lastMessages: [{
|
|
1147
|
+
key: key,
|
|
1148
|
+
messageTimestamp: timeStamp
|
|
1149
|
+
}]
|
|
1150
|
+
}, jid);
|
|
1151
|
+
},
|
|
1152
|
+
getLidUser
|
|
970
1153
|
};
|
|
971
1154
|
};
|
|
972
1155
|
exports.makeChatsSocket = makeChatsSocket;
|