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