@ubedsockets/baileys 1.6.6 → 1.6.7
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 +4 -3
- package/WAProto/WAProto.proto +511 -1215
- package/WAProto/index.js +131318 -59331
- package/lib/Defaults/index.js +92 -76
- package/lib/Signal/Group/ciphertext-message.js +5 -2
- package/lib/Signal/Group/group-session-builder.js +41 -7
- package/lib/Signal/Group/group_cipher.js +51 -37
- package/lib/Signal/Group/index.js +57 -12
- package/lib/Signal/Group/keyhelper.js +44 -7
- package/lib/Signal/Group/sender-chain-key.js +15 -7
- package/lib/Signal/Group/sender-key-distribution-message.js +11 -8
- package/lib/Signal/Group/sender-key-message.js +12 -9
- package/lib/Signal/Group/sender-key-name.js +5 -2
- package/lib/Signal/Group/sender-key-record.js +21 -9
- package/lib/Signal/Group/sender-key-state.js +42 -27
- package/lib/Signal/Group/sender-message-key.js +7 -4
- package/lib/Signal/libsignal.js +90 -347
- package/lib/Socket/Client/index.js +18 -3
- package/lib/Socket/Client/types.js +6 -4
- package/lib/Socket/Client/websocket.js +78 -21
- package/lib/Socket/business.js +43 -162
- package/lib/Socket/chats.js +249 -571
- package/lib/Socket/groups.js +99 -114
- package/lib/Socket/index.js +9 -11
- package/lib/Socket/messages-recv.js +559 -1277
- package/lib/Socket/messages-send.js +669 -674
- package/lib/Socket/newsletter.js +286 -149
- package/lib/Socket/socket.js +235 -548
- package/lib/Types/Auth.js +2 -2
- package/lib/Types/Call.js +2 -2
- package/lib/Types/Chat.js +4 -8
- package/lib/Types/Contact.js +2 -2
- package/lib/Types/Events.js +2 -2
- package/lib/Types/GroupMetadata.js +2 -2
- package/lib/Types/Label.js +5 -3
- package/lib/Types/LabelAssociation.js +5 -3
- package/lib/Types/Message.js +7 -11
- package/lib/Types/Product.js +2 -2
- package/lib/Types/Signal.js +2 -2
- package/lib/Types/Socket.js +2 -3
- package/lib/Types/State.js +2 -56
- package/lib/Types/USync.js +2 -2
- package/lib/Types/index.js +31 -15
- package/lib/Utils/auth-utils.js +136 -239
- package/lib/Utils/business.js +69 -66
- package/lib/Utils/chat-utils.js +238 -380
- package/lib/Utils/crypto.js +127 -56
- package/lib/Utils/decode-wa-message.js +63 -173
- package/lib/Utils/event-buffer.js +70 -174
- package/lib/Utils/generics.js +207 -159
- package/lib/Utils/history.js +53 -93
- package/lib/Utils/index.js +33 -22
- package/lib/Utils/link-preview.js +58 -17
- package/lib/Utils/logger.js +7 -3
- package/lib/Utils/lt-hash.js +46 -3
- package/lib/Utils/make-mutex.js +34 -24
- package/lib/Utils/messages-media.js +744 -483
- package/lib/Utils/messages.js +621 -411
- package/lib/Utils/noise-handler.js +99 -149
- package/lib/Utils/process-message.js +150 -459
- package/lib/Utils/signal.js +73 -112
- package/lib/Utils/use-multi-file-auth-state.js +27 -23
- package/lib/Utils/validate-connection.js +104 -74
- package/lib/WABinary/constants.js +11 -9
- package/lib/WABinary/decode.js +52 -49
- package/lib/WABinary/encode.js +49 -19
- package/lib/WABinary/generic-utils.js +43 -46
- package/lib/WABinary/index.js +21 -6
- package/lib/WABinary/jid-utils.js +45 -72
- package/lib/WABinary/types.js +2 -2
- package/lib/WAM/BinaryInfo.js +5 -2
- package/lib/WAM/constants.js +11958 -19461
- package/lib/WAM/encode.js +22 -17
- package/lib/WAM/index.js +19 -4
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +13 -33
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +14 -11
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +11 -8
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +13 -9
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +22 -20
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +8 -13
- package/lib/WAUSync/Protocols/index.js +20 -6
- package/lib/WAUSync/USyncQuery.js +35 -44
- package/lib/WAUSync/USyncUser.js +5 -10
- package/lib/WAUSync/index.js +19 -4
- package/lib/index.js +70 -11
- package/package.json +60 -100
- package/engine-requirements.js +0 -10
|
@@ -1,68 +1,74 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.makeMessagesSocket = void 0;
|
|
7
|
+
|
|
8
|
+
const boom_1 = require("@hapi/boom");
|
|
9
|
+
const node_cache_1 = __importDefault(require("@cacheable/node-cache"));
|
|
10
|
+
const crypto_1 = require("crypto");
|
|
11
|
+
const WAProto_1 = require("../../WAProto");
|
|
12
|
+
const Defaults_1 = require("../Defaults");
|
|
13
|
+
const Utils_1 = require("../Utils");
|
|
14
|
+
const link_preview_1 = require("../Utils/link-preview");
|
|
15
|
+
const WABinary_1 = require("../WABinary");
|
|
16
|
+
const WAUSync_1 = require("../WAUSync");
|
|
17
|
+
const newsletter_1 = require("./newsletter");
|
|
18
|
+
const aveline = require("./setup");
|
|
19
|
+
|
|
20
|
+
const makeMessagesSocket = (config) => {
|
|
21
|
+
const { logger,
|
|
22
|
+
linkPreviewImageThumbnailWidth,
|
|
23
|
+
generateHighQualityLinkPreview,
|
|
24
|
+
options: axiosOptions,
|
|
25
|
+
patchMessageBeforeSending,
|
|
26
|
+
cachedGroupMetadata,
|
|
27
|
+
} = config;
|
|
28
|
+
|
|
29
|
+
const sock = (0, newsletter_1.makeNewsletterSocket)(config);
|
|
30
|
+
// ⒷⒶⒾⓁⒺⓎⓈ ⒷⓎ ⓋⓎⓏⒺⓃ
|
|
31
|
+
const {
|
|
32
|
+
ev,
|
|
33
|
+
authState,
|
|
34
|
+
processingMutex,
|
|
35
|
+
signalRepository,
|
|
36
|
+
upsertMessage,
|
|
37
|
+
query,
|
|
38
|
+
fetchPrivacySettings,
|
|
39
|
+
sendNode,
|
|
40
|
+
groupMetadata,
|
|
41
|
+
groupToggleEphemeral,
|
|
42
|
+
} = sock;
|
|
43
|
+
const userDevicesCache = config.userDevicesCache || new node_cache_1.default({
|
|
44
|
+
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.USER_DEVICES, // 5 minutes
|
|
45
|
+
useClones: false
|
|
46
|
+
});
|
|
35
47
|
let mediaConn;
|
|
36
|
-
/** Per-socket media host; updated whenever media_conn is fetched. Defaults to the public WhatsApp host. */
|
|
37
|
-
let mediaHost = DEF_MEDIA_HOST;
|
|
38
48
|
const refreshMediaConn = async (forceGet = false) => {
|
|
39
49
|
const media = await mediaConn;
|
|
40
|
-
if (!media || forceGet || new Date().getTime() - media.fetchDate.getTime() > media.ttl * 1000) {
|
|
50
|
+
if (!media || forceGet || (new Date().getTime() - media.fetchDate.getTime()) > media.ttl * 1000) {
|
|
41
51
|
mediaConn = (async () => {
|
|
42
52
|
const result = await query({
|
|
43
53
|
tag: 'iq',
|
|
44
54
|
attrs: {
|
|
45
55
|
type: 'set',
|
|
46
56
|
xmlns: 'w:m',
|
|
47
|
-
to: S_WHATSAPP_NET
|
|
57
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
48
58
|
},
|
|
49
59
|
content: [{ tag: 'media_conn', attrs: {} }]
|
|
50
60
|
});
|
|
51
|
-
const mediaConnNode = getBinaryNodeChild(result, 'media_conn');
|
|
52
|
-
// TODO: explore full length of data that whatsapp provides
|
|
61
|
+
const mediaConnNode = (0, WABinary_1.getBinaryNodeChild)(result, 'media_conn');
|
|
53
62
|
const node = {
|
|
54
|
-
hosts: getBinaryNodeChildren(mediaConnNode, 'host').map(({ attrs }) => ({
|
|
63
|
+
hosts: (0, WABinary_1.getBinaryNodeChildren)(mediaConnNode, 'host').map(({ attrs }) => ({
|
|
55
64
|
hostname: attrs.hostname,
|
|
56
|
-
maxContentLengthBytes: +attrs.maxContentLengthBytes
|
|
65
|
+
maxContentLengthBytes: +attrs.maxContentLengthBytes,
|
|
57
66
|
})),
|
|
58
67
|
auth: mediaConnNode.attrs.auth,
|
|
59
68
|
ttl: +mediaConnNode.attrs.ttl,
|
|
60
69
|
fetchDate: new Date()
|
|
61
70
|
};
|
|
62
71
|
logger.debug('fetched media conn');
|
|
63
|
-
if (node.hosts[0]) {
|
|
64
|
-
mediaHost = node.hosts[0].hostname;
|
|
65
|
-
}
|
|
66
72
|
return node;
|
|
67
73
|
})();
|
|
68
74
|
}
|
|
@@ -71,22 +77,19 @@ export const makeMessagesSocket = (config) => {
|
|
|
71
77
|
/**
|
|
72
78
|
* generic send receipt function
|
|
73
79
|
* used for receipts of phone call, read, delivery etc.
|
|
74
|
-
|
|
80
|
+
*/
|
|
75
81
|
const sendReceipt = async (jid, participant, messageIds, type) => {
|
|
76
|
-
if (!messageIds || messageIds.length === 0) {
|
|
77
|
-
throw new Boom('missing ids in receipt');
|
|
78
|
-
}
|
|
79
82
|
const node = {
|
|
80
83
|
tag: 'receipt',
|
|
81
84
|
attrs: {
|
|
82
|
-
id: messageIds[0]
|
|
83
|
-
}
|
|
85
|
+
id: messageIds[0],
|
|
86
|
+
},
|
|
84
87
|
};
|
|
85
88
|
const isReadReceipt = type === 'read' || type === 'read-self';
|
|
86
89
|
if (isReadReceipt) {
|
|
87
|
-
node.attrs.t = unixTimestampSeconds().toString();
|
|
90
|
+
node.attrs.t = (0, Utils_1.unixTimestampSeconds)().toString();
|
|
88
91
|
}
|
|
89
|
-
if (type === 'sender' && (
|
|
92
|
+
if (type === 'sender' && (0, WABinary_1.isJidUser)(jid)) {
|
|
90
93
|
node.attrs.recipient = jid;
|
|
91
94
|
node.attrs.to = participant;
|
|
92
95
|
}
|
|
@@ -97,7 +100,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
97
100
|
}
|
|
98
101
|
}
|
|
99
102
|
if (type) {
|
|
100
|
-
node.attrs.type = type;
|
|
103
|
+
node.attrs.type = (0, WABinary_1.isJidNewsletter)(jid) ? 'read-self' : type;
|
|
101
104
|
}
|
|
102
105
|
const remainingMessageIds = messageIds.slice(1);
|
|
103
106
|
if (remainingMessageIds.length) {
|
|
@@ -117,7 +120,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
117
120
|
};
|
|
118
121
|
/** Correctly bulk send receipts to multiple chats, participants */
|
|
119
122
|
const sendReceipts = async (keys, type) => {
|
|
120
|
-
const recps = aggregateMessageKeysNotFromMe(keys);
|
|
123
|
+
const recps = (0, Utils_1.aggregateMessageKeysNotFromMe)(keys);
|
|
121
124
|
for (const { jid, participant, messageIds } of recps) {
|
|
122
125
|
await sendReceipt(jid, participant, messageIds, type);
|
|
123
126
|
}
|
|
@@ -131,44 +134,20 @@ export const makeMessagesSocket = (config) => {
|
|
|
131
134
|
};
|
|
132
135
|
/** Fetch all the devices we've to send a message to */
|
|
133
136
|
const getUSyncDevices = async (jids, useCache, ignoreZeroDevices) => {
|
|
137
|
+
var _a;
|
|
134
138
|
const deviceResults = [];
|
|
135
139
|
if (!useCache) {
|
|
136
140
|
logger.debug('not using cache for devices');
|
|
137
141
|
}
|
|
138
142
|
const toFetch = [];
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
const device = decoded?.device;
|
|
144
|
-
const isExplicitDevice = typeof device === 'number' && device >= 0;
|
|
145
|
-
if (isExplicitDevice && user) {
|
|
146
|
-
deviceResults.push({
|
|
147
|
-
user,
|
|
148
|
-
device,
|
|
149
|
-
jid
|
|
150
|
-
});
|
|
151
|
-
return null;
|
|
152
|
-
}
|
|
153
|
-
jid = jidNormalizedUser(jid);
|
|
154
|
-
return { jid, user };
|
|
155
|
-
})
|
|
156
|
-
.filter(jid => jid !== null);
|
|
157
|
-
let mgetDevices;
|
|
158
|
-
if (useCache && userDevicesCache.mget) {
|
|
159
|
-
const usersToFetch = jidsWithUser.map(j => j?.user).filter(Boolean);
|
|
160
|
-
mgetDevices = await userDevicesCache.mget(usersToFetch);
|
|
161
|
-
}
|
|
162
|
-
for (const { jid, user } of jidsWithUser) {
|
|
143
|
+
jids = Array.from(new Set(jids));
|
|
144
|
+
for (let jid of jids) {
|
|
145
|
+
const user = (_a = (0, WABinary_1.jidDecode)(jid)) === null || _a === void 0 ? void 0 : _a.user;
|
|
146
|
+
jid = (0, WABinary_1.jidNormalizedUser)(jid);
|
|
163
147
|
if (useCache) {
|
|
164
|
-
const devices =
|
|
165
|
-
(userDevicesCache.mget ? undefined : (await userDevicesCache.get(user)));
|
|
148
|
+
const devices = userDevicesCache.get(user);
|
|
166
149
|
if (devices) {
|
|
167
|
-
|
|
168
|
-
...d,
|
|
169
|
-
jid: jidEncode(d.user, d.server, d.device)
|
|
170
|
-
}));
|
|
171
|
-
deviceResults.push(...devicesWithJid);
|
|
150
|
+
deviceResults.push(...devices);
|
|
172
151
|
logger.trace({ user }, 'using cache for devices');
|
|
173
152
|
}
|
|
174
153
|
else {
|
|
@@ -182,270 +161,157 @@ export const makeMessagesSocket = (config) => {
|
|
|
182
161
|
if (!toFetch.length) {
|
|
183
162
|
return deviceResults;
|
|
184
163
|
}
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const user = jidDecode(jid)?.user;
|
|
189
|
-
if (user)
|
|
190
|
-
requestedLidUsers.add(user);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
const query = new USyncQuery().withContext('message').withDeviceProtocol().withLIDProtocol();
|
|
164
|
+
const query = new WAUSync_1.USyncQuery()
|
|
165
|
+
.withContext('message')
|
|
166
|
+
.withDeviceProtocol();
|
|
194
167
|
for (const jid of toFetch) {
|
|
195
|
-
query.withUser(new USyncUser().withId(jid));
|
|
168
|
+
query.withUser(new WAUSync_1.USyncUser().withId(jid));
|
|
196
169
|
}
|
|
197
170
|
const result = await sock.executeUSyncQuery(query);
|
|
198
171
|
if (result) {
|
|
199
|
-
|
|
200
|
-
const lidResults = result.list.filter(a => !!a.lid);
|
|
201
|
-
if (lidResults.length > 0) {
|
|
202
|
-
logger.trace('Storing LID maps from device call');
|
|
203
|
-
await signalRepository.lidMapping.storeLIDPNMappings(lidResults.map(a => ({ lid: a.lid, pn: a.id })));
|
|
204
|
-
// Force-refresh sessions for newly mapped LIDs to align identity addressing
|
|
205
|
-
try {
|
|
206
|
-
const lids = lidResults.map(a => a.lid);
|
|
207
|
-
if (lids.length) {
|
|
208
|
-
await assertSessions(lids, true);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
catch (e) {
|
|
212
|
-
logger.warn({ e, count: lidResults.length }, 'failed to assert sessions for newly mapped LIDs');
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
const extracted = extractDeviceJids(result?.list, authState.creds.me.id, authState.creds.me.lid, ignoreZeroDevices);
|
|
172
|
+
const extracted = (0, Utils_1.extractDeviceJids)(result === null || result === void 0 ? void 0 : result.list, authState.creds.me.id, ignoreZeroDevices);
|
|
216
173
|
const deviceMap = {};
|
|
217
174
|
for (const item of extracted) {
|
|
218
175
|
deviceMap[item.user] = deviceMap[item.user] || [];
|
|
219
|
-
deviceMap[item.user]
|
|
220
|
-
|
|
221
|
-
// Process each user's devices as a group for bulk LID migration
|
|
222
|
-
for (const [user, userDevices] of Object.entries(deviceMap)) {
|
|
223
|
-
const isLidUser = requestedLidUsers.has(user);
|
|
224
|
-
// Process all devices for this user
|
|
225
|
-
for (const item of userDevices) {
|
|
226
|
-
const finalJid = isLidUser
|
|
227
|
-
? jidEncode(user, item.server, item.device)
|
|
228
|
-
: jidEncode(item.user, item.server, item.device);
|
|
229
|
-
deviceResults.push({
|
|
230
|
-
...item,
|
|
231
|
-
jid: finalJid
|
|
232
|
-
});
|
|
233
|
-
logger.debug({
|
|
234
|
-
user: item.user,
|
|
235
|
-
device: item.device,
|
|
236
|
-
finalJid,
|
|
237
|
-
usedLid: isLidUser
|
|
238
|
-
}, 'Processed device with LID priority');
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
await devicesMutex.mutex(async () => {
|
|
242
|
-
if (userDevicesCache.mset) {
|
|
243
|
-
// if the cache supports mset, we can set all devices in one go
|
|
244
|
-
await userDevicesCache.mset(Object.entries(deviceMap).map(([key, value]) => ({ key, value })));
|
|
245
|
-
}
|
|
246
|
-
else {
|
|
247
|
-
for (const key in deviceMap) {
|
|
248
|
-
if (deviceMap[key])
|
|
249
|
-
await userDevicesCache.set(key, deviceMap[key]);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
});
|
|
253
|
-
const userDeviceUpdates = {};
|
|
254
|
-
for (const [userId, devices] of Object.entries(deviceMap)) {
|
|
255
|
-
if (devices && devices.length > 0) {
|
|
256
|
-
userDeviceUpdates[userId] = devices.map(d => d.device?.toString() || '0');
|
|
257
|
-
}
|
|
176
|
+
deviceMap[item.user].push(item);
|
|
177
|
+
deviceResults.push(item);
|
|
258
178
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
await authState.keys.set({ 'device-list': userDeviceUpdates });
|
|
262
|
-
logger.debug({ userCount: Object.keys(userDeviceUpdates).length }, 'stored user device lists for bulk migration');
|
|
263
|
-
}
|
|
264
|
-
catch (error) {
|
|
265
|
-
logger.warn({ error }, 'failed to store user device lists');
|
|
266
|
-
}
|
|
179
|
+
for (const key in deviceMap) {
|
|
180
|
+
userDevicesCache.set(key, deviceMap[key]);
|
|
267
181
|
}
|
|
268
182
|
}
|
|
269
183
|
return deviceResults;
|
|
270
184
|
};
|
|
271
|
-
/**
|
|
272
|
-
* Update Member Label
|
|
273
|
-
*/
|
|
274
|
-
const updateMemberLabel = (jid, memberLabel) => {
|
|
275
|
-
return relayMessage(jid, {
|
|
276
|
-
protocolMessage: {
|
|
277
|
-
type: proto.Message.ProtocolMessage.Type.GROUP_MEMBER_LABEL_CHANGE,
|
|
278
|
-
memberLabel: {
|
|
279
|
-
label: memberLabel?.slice(0, 30),
|
|
280
|
-
labelTimestamp: unixTimestampSeconds()
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}, {
|
|
284
|
-
additionalNodes: [
|
|
285
|
-
{
|
|
286
|
-
tag: 'meta',
|
|
287
|
-
attrs: {
|
|
288
|
-
tag_reason: 'user_update',
|
|
289
|
-
appdata: 'member_tag'
|
|
290
|
-
},
|
|
291
|
-
content: undefined
|
|
292
|
-
}
|
|
293
|
-
]
|
|
294
|
-
});
|
|
295
|
-
};
|
|
296
185
|
const assertSessions = async (jids, force) => {
|
|
297
186
|
let didFetchNewSession = false;
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
187
|
+
let jidsRequiringFetch = [];
|
|
188
|
+
if (force) {
|
|
189
|
+
jidsRequiringFetch = jids;
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
const addrs = jids.map(jid => (signalRepository
|
|
193
|
+
.jidToSignalProtocolAddress(jid)));
|
|
194
|
+
const sessions = await authState.keys.get('session', addrs);
|
|
195
|
+
for (const jid of jids) {
|
|
196
|
+
const signalId = signalRepository
|
|
197
|
+
.jidToSignalProtocolAddress(jid);
|
|
198
|
+
if (!sessions[signalId]) {
|
|
199
|
+
jidsRequiringFetch.push(jid);
|
|
306
200
|
}
|
|
307
201
|
}
|
|
308
|
-
jidsRequiringFetch.push(jid);
|
|
309
202
|
}
|
|
310
203
|
if (jidsRequiringFetch.length) {
|
|
311
|
-
|
|
312
|
-
const wireJids = [
|
|
313
|
-
...jidsRequiringFetch.filter(jid => !!isLidUser(jid) || !!isHostedLidUser(jid)),
|
|
314
|
-
...((await signalRepository.lidMapping.getLIDsForPNs(jidsRequiringFetch.filter(jid => !!isPnUser(jid) || !!isHostedPnUser(jid)))) || []).map(a => a.lid)
|
|
315
|
-
];
|
|
316
|
-
logger.debug({ jidsRequiringFetch, wireJids }, 'fetching sessions');
|
|
204
|
+
logger.debug({ jidsRequiringFetch }, 'fetching sessions');
|
|
317
205
|
const result = await query({
|
|
318
206
|
tag: 'iq',
|
|
319
207
|
attrs: {
|
|
320
208
|
xmlns: 'encrypt',
|
|
321
209
|
type: 'get',
|
|
322
|
-
to: S_WHATSAPP_NET
|
|
210
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
323
211
|
},
|
|
324
212
|
content: [
|
|
325
213
|
{
|
|
326
214
|
tag: 'key',
|
|
327
215
|
attrs: {},
|
|
328
|
-
content:
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
return { tag: 'user', attrs };
|
|
333
|
-
})
|
|
216
|
+
content: jidsRequiringFetch.map(jid => ({
|
|
217
|
+
tag: 'user',
|
|
218
|
+
attrs: { jid },
|
|
219
|
+
}))
|
|
334
220
|
}
|
|
335
221
|
]
|
|
336
222
|
});
|
|
337
|
-
await parseAndInjectE2ESessions(result, signalRepository);
|
|
223
|
+
await (0, Utils_1.parseAndInjectE2ESessions)(result, signalRepository);
|
|
338
224
|
didFetchNewSession = true;
|
|
339
225
|
}
|
|
340
226
|
return didFetchNewSession;
|
|
341
227
|
};
|
|
342
228
|
const sendPeerDataOperationMessage = async (pdoMessage) => {
|
|
229
|
+
var _a;
|
|
343
230
|
//TODO: for later, abstract the logic to send a Peer Message instead of just PDO - useful for App State Key Resync with phone
|
|
344
|
-
if (!authState.creds.me
|
|
345
|
-
throw new Boom('Not authenticated');
|
|
231
|
+
if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
|
|
232
|
+
throw new boom_1.Boom('Not authenticated');
|
|
346
233
|
}
|
|
347
234
|
const protocolMessage = {
|
|
348
235
|
protocolMessage: {
|
|
349
236
|
peerDataOperationRequestMessage: pdoMessage,
|
|
350
|
-
type: proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_MESSAGE
|
|
237
|
+
type: WAProto_1.proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_MESSAGE
|
|
351
238
|
}
|
|
352
239
|
};
|
|
353
|
-
const meJid = jidNormalizedUser(authState.creds.me.id);
|
|
240
|
+
const meJid = (0, WABinary_1.jidNormalizedUser)(authState.creds.me.id);
|
|
354
241
|
const msgId = await relayMessage(meJid, protocolMessage, {
|
|
355
242
|
additionalAttributes: {
|
|
356
243
|
category: 'peer',
|
|
357
|
-
|
|
244
|
+
// eslint-disable-next-line camelcase
|
|
245
|
+
push_priority: 'high_force',
|
|
358
246
|
},
|
|
359
|
-
additionalNodes: [
|
|
360
|
-
{
|
|
361
|
-
tag: 'meta',
|
|
362
|
-
attrs: { appdata: 'default' }
|
|
363
|
-
}
|
|
364
|
-
]
|
|
365
247
|
});
|
|
366
248
|
return msgId;
|
|
367
249
|
};
|
|
368
|
-
const createParticipantNodes = async (
|
|
369
|
-
|
|
370
|
-
|
|
250
|
+
const createParticipantNodes = async (jids, message, extraAttrs) => {
|
|
251
|
+
let patched = await patchMessageBeforeSending(message, jids);
|
|
252
|
+
if (!Array.isArray(patched)) {
|
|
253
|
+
patched = jids ? jids.map(jid => ({ recipientJid: jid, ...patched })) : [patched];
|
|
371
254
|
}
|
|
372
|
-
const patched = await patchMessageBeforeSending(message, recipientJids);
|
|
373
|
-
const patchedMessages = Array.isArray(patched)
|
|
374
|
-
? patched
|
|
375
|
-
: recipientJids.map(jid => ({ recipientJid: jid, message: patched }));
|
|
376
255
|
let shouldIncludeDeviceIdentity = false;
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
try {
|
|
382
|
-
if (!jid)
|
|
383
|
-
return null;
|
|
384
|
-
let msgToEncrypt = patchedMessage;
|
|
385
|
-
if (dsmMessage) {
|
|
386
|
-
const { user: targetUser } = jidDecode(jid);
|
|
387
|
-
const { user: ownPnUser } = jidDecode(meId);
|
|
388
|
-
const ownLidUser = meLidUser;
|
|
389
|
-
const isOwnUser = targetUser === ownPnUser || (ownLidUser && targetUser === ownLidUser);
|
|
390
|
-
const isExactSenderDevice = jid === meId || (meLid && jid === meLid);
|
|
391
|
-
if (isOwnUser && !isExactSenderDevice) {
|
|
392
|
-
msgToEncrypt = dsmMessage;
|
|
393
|
-
logger.debug({ jid, targetUser }, 'Using DSM for own device');
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
const bytes = encodeWAMessage(msgToEncrypt);
|
|
397
|
-
const mutexKey = jid;
|
|
398
|
-
const node = await encryptionMutex.mutex(mutexKey, async () => {
|
|
399
|
-
const { type, ciphertext } = await signalRepository.encryptMessage({ jid, data: bytes });
|
|
400
|
-
if (type === 'pkmsg') {
|
|
401
|
-
shouldIncludeDeviceIdentity = true;
|
|
402
|
-
}
|
|
403
|
-
return {
|
|
404
|
-
tag: 'to',
|
|
405
|
-
attrs: { jid },
|
|
406
|
-
content: [
|
|
407
|
-
{
|
|
408
|
-
tag: 'enc',
|
|
409
|
-
attrs: { v: '2', type, ...(extraAttrs || {}) },
|
|
410
|
-
content: ciphertext
|
|
411
|
-
}
|
|
412
|
-
]
|
|
413
|
-
};
|
|
414
|
-
});
|
|
415
|
-
return node;
|
|
256
|
+
const nodes = await Promise.all(patched.map(async (patchedMessageWithJid) => {
|
|
257
|
+
const { recipientJid: jid, ...patchedMessage } = patchedMessageWithJid;
|
|
258
|
+
if (!jid) {
|
|
259
|
+
return {};
|
|
416
260
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
261
|
+
const bytes = (0, Utils_1.encodeWAMessage)(patchedMessage);
|
|
262
|
+
const { type, ciphertext } = await signalRepository
|
|
263
|
+
.encryptMessage({ jid, data: bytes });
|
|
264
|
+
if (type === 'pkmsg') {
|
|
265
|
+
shouldIncludeDeviceIdentity = true;
|
|
420
266
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
267
|
+
const node = {
|
|
268
|
+
tag: 'to',
|
|
269
|
+
attrs: { jid },
|
|
270
|
+
content: [{
|
|
271
|
+
tag: 'enc',
|
|
272
|
+
attrs: {
|
|
273
|
+
v: '2',
|
|
274
|
+
type,
|
|
275
|
+
...extraAttrs || {}
|
|
276
|
+
},
|
|
277
|
+
content: ciphertext
|
|
278
|
+
}]
|
|
279
|
+
};
|
|
280
|
+
return node;
|
|
281
|
+
}));
|
|
426
282
|
return { nodes, shouldIncludeDeviceIdentity };
|
|
427
283
|
};
|
|
428
|
-
const relayMessage = async (
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
284
|
+
const relayMessage = async (
|
|
285
|
+
jid,
|
|
286
|
+
message,
|
|
287
|
+
{
|
|
288
|
+
messageId:
|
|
289
|
+
msgId,
|
|
290
|
+
participant,
|
|
291
|
+
additionalAttributes,
|
|
292
|
+
additionalNodes,
|
|
293
|
+
useUserDevicesCache,
|
|
294
|
+
useCachedGroupMetadata,
|
|
295
|
+
statusJidList, AI = true }) => {
|
|
296
|
+
var _a;
|
|
297
|
+
const meId = authState.creds.me.id;
|
|
298
|
+
let shouldIncludeDeviceIdentity = false;
|
|
299
|
+
const { user, server } = (0, WABinary_1.jidDecode)(jid);
|
|
433
300
|
const statusJid = 'status@broadcast';
|
|
434
|
-
const { user, server } = jidDecode(jid);
|
|
435
301
|
const isGroup = server === 'g.us';
|
|
302
|
+
const isPrivatee = server === 's.whatsapp.net'
|
|
303
|
+
const isNewsletter = server === 'newsletter';
|
|
436
304
|
const isStatus = jid === statusJid;
|
|
437
305
|
const isLid = server === 'lid';
|
|
438
|
-
const
|
|
439
|
-
const
|
|
440
|
-
|
|
441
|
-
msgId = msgId || generateMessageIDV2(meId);
|
|
306
|
+
const messages = Utils_1.normalizeMessageContent(message)
|
|
307
|
+
const pollMessage = messages.pollCreationMessage || messages.pollCreationMessageV2 || messages.pollCreationMessageV3
|
|
308
|
+
msgId = msgId || (0, Utils_1.generateMessageIDV2)((_a = sock.user) === null || _a === void 0 ? void 0 : _a.id);
|
|
442
309
|
useUserDevicesCache = useUserDevicesCache !== false;
|
|
443
310
|
useCachedGroupMetadata = useCachedGroupMetadata !== false && !isStatus;
|
|
444
311
|
const participants = [];
|
|
445
|
-
const destinationJid = !isStatus ?
|
|
312
|
+
const destinationJid = (!isStatus) ? (0, WABinary_1.jidEncode)(user, isLid ? 'lid' : isGroup ? 'g.us' : isNewsletter ? 'newsletter' : 's.whatsapp.net') : statusJid;
|
|
446
313
|
const binaryNodeContent = [];
|
|
447
314
|
const devices = [];
|
|
448
|
-
let reportingMessage;
|
|
449
315
|
const meMsg = {
|
|
450
316
|
deviceSentMessage: {
|
|
451
317
|
destinationJid,
|
|
@@ -455,274 +321,161 @@ export const makeMessagesSocket = (config) => {
|
|
|
455
321
|
};
|
|
456
322
|
const extraAttrs = {};
|
|
457
323
|
if (participant) {
|
|
324
|
+
// when the retry request is not for a group
|
|
325
|
+
// only send to the specific device that asked for a retry
|
|
326
|
+
// otherwise the message is sent out to every device that should be a recipient
|
|
458
327
|
if (!isGroup && !isStatus) {
|
|
459
|
-
additionalAttributes = { ...additionalAttributes, device_fanout: 'false' };
|
|
328
|
+
additionalAttributes = { ...additionalAttributes, 'device_fanout': 'false' };
|
|
460
329
|
}
|
|
461
|
-
const { user, device } = jidDecode(participant.jid);
|
|
462
|
-
devices.push({
|
|
463
|
-
user,
|
|
464
|
-
device,
|
|
465
|
-
jid: participant.jid
|
|
466
|
-
});
|
|
330
|
+
const { user, device } = (0, WABinary_1.jidDecode)(participant.jid);
|
|
331
|
+
devices.push({ user, device });
|
|
467
332
|
}
|
|
468
333
|
await authState.keys.transaction(async () => {
|
|
334
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
469
335
|
const mediaType = getMediaType(message);
|
|
470
336
|
if (mediaType) {
|
|
471
337
|
extraAttrs['mediatype'] = mediaType;
|
|
472
338
|
}
|
|
473
|
-
if (
|
|
474
|
-
|
|
475
|
-
const bytes = encodeNewsletterMessage(patched);
|
|
476
|
-
binaryNodeContent.push({
|
|
477
|
-
tag: 'plaintext',
|
|
478
|
-
attrs: {},
|
|
479
|
-
content: bytes
|
|
480
|
-
});
|
|
481
|
-
const stanza = {
|
|
482
|
-
tag: 'message',
|
|
483
|
-
attrs: {
|
|
484
|
-
to: jid,
|
|
485
|
-
id: msgId,
|
|
486
|
-
type: getMessageType(message),
|
|
487
|
-
...(additionalAttributes || {})
|
|
488
|
-
},
|
|
489
|
-
content: binaryNodeContent
|
|
490
|
-
};
|
|
491
|
-
logger.debug({ msgId }, `sending newsletter message to ${jid}`);
|
|
492
|
-
await sendNode(stanza);
|
|
493
|
-
return;
|
|
494
|
-
}
|
|
495
|
-
if (normalizeMessageContent(message)?.pinInChatMessage || normalizeMessageContent(message)?.reactionMessage) {
|
|
496
|
-
extraAttrs['decrypt-fail'] = 'hide'; // todo: expand for reactions and other types
|
|
339
|
+
if ((_a = (0, Utils_1.normalizeMessageContent)(message)) === null || _a === void 0 ? void 0 : _a.pinInChatMessage) {
|
|
340
|
+
extraAttrs['decrypt-fail'] = 'hide';
|
|
497
341
|
}
|
|
498
|
-
if (
|
|
342
|
+
if (isGroup || isStatus) {
|
|
499
343
|
const [groupData, senderKeyMap] = await Promise.all([
|
|
500
344
|
(async () => {
|
|
501
|
-
let groupData = useCachedGroupMetadata && cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined;
|
|
502
|
-
if (groupData && Array.isArray(groupData
|
|
345
|
+
let groupData = useCachedGroupMetadata && cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined;
|
|
346
|
+
if (groupData && Array.isArray(groupData === null || groupData === void 0 ? void 0 : groupData.participants)) {
|
|
503
347
|
logger.trace({ jid, participants: groupData.participants.length }, 'using cached group metadata');
|
|
504
348
|
}
|
|
505
349
|
else if (!isStatus) {
|
|
506
|
-
groupData = await groupMetadata(jid);
|
|
350
|
+
groupData = await groupMetadata(jid);
|
|
507
351
|
}
|
|
508
352
|
return groupData;
|
|
509
353
|
})(),
|
|
510
354
|
(async () => {
|
|
511
355
|
if (!participant && !isStatus) {
|
|
512
|
-
|
|
513
|
-
// on participant change in group, we should do sender memory manipulation
|
|
514
|
-
const result = await authState.keys.get('sender-key-memory', [jid]); // TODO: check out what if the sender key memory doesn't include the LID stuff now?
|
|
356
|
+
const result = await authState.keys.get('sender-key-memory', [jid]);
|
|
515
357
|
return result[jid] || {};
|
|
516
358
|
}
|
|
517
359
|
return {};
|
|
518
360
|
})()
|
|
519
361
|
]);
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
...
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
...additionalAttributes,
|
|
535
|
-
addressing_mode: groupData?.addressingMode || 'lid'
|
|
536
|
-
};
|
|
362
|
+
if (!participant) {
|
|
363
|
+
const participantsList = (groupData && !isStatus) ? groupData.participants.map(p => p.id) : [];
|
|
364
|
+
if (isStatus && statusJidList) {
|
|
365
|
+
participantsList.push(...statusJidList);
|
|
366
|
+
}
|
|
367
|
+
if (!isStatus) {
|
|
368
|
+
additionalAttributes = {
|
|
369
|
+
...additionalAttributes,
|
|
370
|
+
// eslint-disable-next-line camelcase
|
|
371
|
+
addressing_mode: (groupData === null || groupData === void 0 ? void 0 : groupData.addressingMode) || 'pn'
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
const additionalDevices = await getUSyncDevices(participantsList, !!useUserDevicesCache, false);
|
|
375
|
+
devices.push(...additionalDevices);
|
|
537
376
|
}
|
|
538
377
|
const patched = await patchMessageBeforeSending(message);
|
|
539
378
|
if (Array.isArray(patched)) {
|
|
540
|
-
throw new Boom('Per-jid patching is not supported in groups');
|
|
379
|
+
throw new boom_1.Boom('Per-jid patching is not supported in groups');
|
|
541
380
|
}
|
|
542
|
-
const bytes = encodeWAMessage(patched);
|
|
543
|
-
reportingMessage = patched;
|
|
544
|
-
const groupAddressingMode = additionalAttributes?.['addressing_mode'] || groupData?.addressingMode || 'lid';
|
|
545
|
-
const groupSenderIdentity = groupAddressingMode === 'lid' && meLid ? meLid : meId;
|
|
381
|
+
const bytes = (0, Utils_1.encodeWAMessage)(patched);
|
|
546
382
|
const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage({
|
|
547
383
|
group: destinationJid,
|
|
548
384
|
data: bytes,
|
|
549
|
-
meId
|
|
385
|
+
meId,
|
|
550
386
|
});
|
|
551
|
-
const
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
const
|
|
555
|
-
if (
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
//todo: revamp all this logic
|
|
560
|
-
// the goal is to follow with what I said above for each group, and instead of a true false map of ids, we can set an array full of those the app has already sent pkmsgs
|
|
561
|
-
senderKeyRecipients.push(deviceJid);
|
|
562
|
-
senderKeyMap[deviceJid] = true;
|
|
387
|
+
const senderKeyJids = [];
|
|
388
|
+
// ensure a connection is established with every device
|
|
389
|
+
for (const { user, device } of devices) {
|
|
390
|
+
const jid = (0, WABinary_1.jidEncode)(user, (groupData === null || groupData === void 0 ? void 0 : groupData.addressingMode) === 'lid' ? 'lid' : 's.whatsapp.net', device);
|
|
391
|
+
if (!senderKeyMap[jid] || !!participant) {
|
|
392
|
+
senderKeyJids.push(jid);
|
|
393
|
+
// store that this person has had the sender keys sent to them
|
|
394
|
+
senderKeyMap[jid] = true;
|
|
563
395
|
}
|
|
564
396
|
}
|
|
565
|
-
if
|
|
566
|
-
|
|
397
|
+
// if there are some participants with whom the session has not been established
|
|
398
|
+
// if there are, we re-send the senderkey
|
|
399
|
+
if (senderKeyJids.length) {
|
|
400
|
+
logger.debug({ senderKeyJids }, 'sending new sender key');
|
|
567
401
|
const senderKeyMsg = {
|
|
568
402
|
senderKeyDistributionMessage: {
|
|
569
403
|
axolotlSenderKeyDistributionMessage: senderKeyDistributionMessage,
|
|
570
404
|
groupId: destinationJid
|
|
571
405
|
}
|
|
572
406
|
};
|
|
573
|
-
|
|
574
|
-
await
|
|
575
|
-
const result = await createParticipantNodes(senderKeyRecipients, senderKeyMsg, extraAttrs);
|
|
407
|
+
await assertSessions(senderKeyJids, false);
|
|
408
|
+
const result = await createParticipantNodes(senderKeyJids, senderKeyMsg, extraAttrs);
|
|
576
409
|
shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || result.shouldIncludeDeviceIdentity;
|
|
577
410
|
participants.push(...result.nodes);
|
|
578
411
|
}
|
|
579
412
|
binaryNodeContent.push({
|
|
580
413
|
tag: 'enc',
|
|
581
|
-
attrs: { v: '2', type: 'skmsg'
|
|
414
|
+
attrs: { v: '2', type: 'skmsg' },
|
|
582
415
|
content: ciphertext
|
|
583
416
|
});
|
|
584
417
|
await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } });
|
|
585
418
|
}
|
|
586
|
-
else {
|
|
587
|
-
//
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
ownId = meLid;
|
|
592
|
-
logger.debug({ to: jid, ownId }, 'Using LID identity for @lid conversation');
|
|
419
|
+
else if (isNewsletter) {
|
|
420
|
+
// Message edit
|
|
421
|
+
if ((_b = message.protocolMessage) === null || _b === void 0 ? void 0 : _b.editedMessage) {
|
|
422
|
+
msgId = (_c = message.protocolMessage.key) === null || _c === void 0 ? void 0 : _c.id;
|
|
423
|
+
message = message.protocolMessage.editedMessage;
|
|
593
424
|
}
|
|
594
|
-
|
|
595
|
-
|
|
425
|
+
// Message delete
|
|
426
|
+
if (((_d = message.protocolMessage) === null || _d === void 0 ? void 0 : _d.type) === WAProto_1.proto.Message.ProtocolMessage.Type.REVOKE) {
|
|
427
|
+
msgId = (_e = message.protocolMessage.key) === null || _e === void 0 ? void 0 : _e.id;
|
|
428
|
+
message = {};
|
|
596
429
|
}
|
|
597
|
-
const
|
|
598
|
-
if (
|
|
599
|
-
|
|
600
|
-
reportingMessage = Array.isArray(patchedForReporting)
|
|
601
|
-
? patchedForReporting.find(item => item.recipientJid === jid) || patchedForReporting[0]
|
|
602
|
-
: patchedForReporting;
|
|
430
|
+
const patched = await patchMessageBeforeSending(message, []);
|
|
431
|
+
if (Array.isArray(patched)) {
|
|
432
|
+
throw new boom_1.Boom('Per-jid patching is not supported in channel');
|
|
603
433
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
jid: jidEncode(ownUserForAddressing, ownUserServer, 0)
|
|
618
|
-
});
|
|
434
|
+
const bytes = (0, Utils_1.encodeNewsletterMessage)(patched);
|
|
435
|
+
binaryNodeContent.push({
|
|
436
|
+
tag: 'plaintext',
|
|
437
|
+
attrs: mediaType ? { mediatype: mediaType } : {},
|
|
438
|
+
content: bytes
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
const { user: meUser } = (0, WABinary_1.jidDecode)(meId);
|
|
443
|
+
if (!participant) {
|
|
444
|
+
devices.push({ user });
|
|
445
|
+
if (user !== meUser) {
|
|
446
|
+
devices.push({ user: meUser });
|
|
619
447
|
}
|
|
620
|
-
if (additionalAttributes
|
|
621
|
-
|
|
622
|
-
devices.
|
|
623
|
-
// Use conversation-appropriate sender identity
|
|
624
|
-
const senderIdentity = isLid && meLid
|
|
625
|
-
? jidEncode(jidDecode(meLid)?.user, 'lid', undefined)
|
|
626
|
-
: jidEncode(jidDecode(meId)?.user, 's.whatsapp.net', undefined);
|
|
627
|
-
// Enumerate devices for sender and target with consistent addressing
|
|
628
|
-
const sessionDevices = await getUSyncDevices([senderIdentity, jid], true, false);
|
|
629
|
-
devices.push(...sessionDevices);
|
|
630
|
-
logger.debug({
|
|
631
|
-
deviceCount: devices.length,
|
|
632
|
-
devices: devices.map(d => `${d.user}:${d.device}@${jidDecode(d.jid)?.server}`)
|
|
633
|
-
}, 'Device enumeration complete with unified addressing');
|
|
448
|
+
if ((additionalAttributes === null || additionalAttributes === void 0 ? void 0 : additionalAttributes['category']) !== 'peer') {
|
|
449
|
+
const additionalDevices = await getUSyncDevices([meId, jid], !!useUserDevicesCache, true);
|
|
450
|
+
devices.push(...additionalDevices);
|
|
634
451
|
}
|
|
635
452
|
}
|
|
636
|
-
const
|
|
637
|
-
const
|
|
638
|
-
const
|
|
639
|
-
const { user
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
const isExactSenderDevice = jid === meId || (meLid && jid === meLid);
|
|
643
|
-
if (isExactSenderDevice) {
|
|
644
|
-
logger.debug({ jid, meId, meLid }, 'Skipping exact sender device (whatsmeow pattern)');
|
|
645
|
-
continue;
|
|
646
|
-
}
|
|
647
|
-
// Check if this is our device (could match either PN or LID user)
|
|
648
|
-
const isMe = user === mePnUser || user === meLidUser;
|
|
453
|
+
const allJids = [];
|
|
454
|
+
const meJids = [];
|
|
455
|
+
const otherJids = [];
|
|
456
|
+
for (const { user, device } of devices) {
|
|
457
|
+
const isMe = user === meUser;
|
|
458
|
+
const jid = (0, WABinary_1.jidEncode)(isMe && isLid ? ((_g = (_f = authState.creds) === null || _f === void 0 ? void 0 : _f.me) === null || _g === void 0 ? void 0 : _g.lid.split(':')[0]) || user : user, isLid ? 'lid' : 's.whatsapp.net', device);
|
|
649
459
|
if (isMe) {
|
|
650
|
-
|
|
460
|
+
meJids.push(jid);
|
|
651
461
|
}
|
|
652
462
|
else {
|
|
653
|
-
|
|
463
|
+
otherJids.push(jid);
|
|
654
464
|
}
|
|
655
|
-
|
|
465
|
+
allJids.push(jid);
|
|
656
466
|
}
|
|
657
|
-
await assertSessions(
|
|
467
|
+
await assertSessions(allJids, false);
|
|
658
468
|
const [{ nodes: meNodes, shouldIncludeDeviceIdentity: s1 }, { nodes: otherNodes, shouldIncludeDeviceIdentity: s2 }] = await Promise.all([
|
|
659
|
-
|
|
660
|
-
createParticipantNodes(
|
|
661
|
-
createParticipantNodes(otherRecipients, message, extraAttrs, meMsg)
|
|
469
|
+
createParticipantNodes(meJids, meMsg, extraAttrs),
|
|
470
|
+
createParticipantNodes(otherJids, message, extraAttrs)
|
|
662
471
|
]);
|
|
663
472
|
participants.push(...meNodes);
|
|
664
473
|
participants.push(...otherNodes);
|
|
665
|
-
if (meRecipients.length > 0 || otherRecipients.length > 0) {
|
|
666
|
-
extraAttrs['phash'] = generateParticipantHashV2([...meRecipients, ...otherRecipients]);
|
|
667
|
-
}
|
|
668
474
|
shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || s1 || s2;
|
|
669
475
|
}
|
|
670
|
-
if (isRetryResend) {
|
|
671
|
-
const isParticipantLid = isLidUser(participant.jid);
|
|
672
|
-
const isMe = areJidsSameUser(participant.jid, isParticipantLid ? meLid : meId);
|
|
673
|
-
let messageToSend = message;
|
|
674
|
-
if (isGroupOrStatus) {
|
|
675
|
-
let groupSenderIdentity;
|
|
676
|
-
if (meLid && (await signalRepository.hasSenderKey({ group: destinationJid, meId: meLid }))) {
|
|
677
|
-
groupSenderIdentity = meLid;
|
|
678
|
-
}
|
|
679
|
-
else if (await signalRepository.hasSenderKey({ group: destinationJid, meId })) {
|
|
680
|
-
groupSenderIdentity = meId;
|
|
681
|
-
}
|
|
682
|
-
if (groupSenderIdentity) {
|
|
683
|
-
try {
|
|
684
|
-
const skdm = await signalRepository.getSenderKeyDistributionMessage({
|
|
685
|
-
group: destinationJid,
|
|
686
|
-
meId: groupSenderIdentity
|
|
687
|
-
});
|
|
688
|
-
messageToSend = {
|
|
689
|
-
...message,
|
|
690
|
-
senderKeyDistributionMessage: {
|
|
691
|
-
groupId: destinationJid,
|
|
692
|
-
axolotlSenderKeyDistributionMessage: skdm
|
|
693
|
-
}
|
|
694
|
-
};
|
|
695
|
-
}
|
|
696
|
-
catch (err) {
|
|
697
|
-
logger.warn({ err, jid: destinationJid }, 'failed to build SKDM for retry, sending without it');
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
const encodedMessageToSend = isMe
|
|
702
|
-
? encodeWAMessage({
|
|
703
|
-
deviceSentMessage: {
|
|
704
|
-
destinationJid,
|
|
705
|
-
message: messageToSend
|
|
706
|
-
}
|
|
707
|
-
})
|
|
708
|
-
: encodeWAMessage(messageToSend);
|
|
709
|
-
const { type, ciphertext: encryptedContent } = await signalRepository.encryptMessage({
|
|
710
|
-
data: encodedMessageToSend,
|
|
711
|
-
jid: participant.jid
|
|
712
|
-
});
|
|
713
|
-
binaryNodeContent.push({
|
|
714
|
-
tag: 'enc',
|
|
715
|
-
attrs: {
|
|
716
|
-
v: '2',
|
|
717
|
-
type,
|
|
718
|
-
count: participant.count.toString()
|
|
719
|
-
},
|
|
720
|
-
content: encryptedContent
|
|
721
|
-
});
|
|
722
|
-
}
|
|
723
476
|
if (participants.length) {
|
|
724
|
-
if (additionalAttributes
|
|
725
|
-
const peerNode = participants[0]
|
|
477
|
+
if ((additionalAttributes === null || additionalAttributes === void 0 ? void 0 : additionalAttributes['category']) === 'peer') {
|
|
478
|
+
const peerNode = (_j = (_h = participants[0]) === null || _h === void 0 ? void 0 : _h.content) === null || _j === void 0 ? void 0 : _j[0];
|
|
726
479
|
if (peerNode) {
|
|
727
480
|
binaryNodeContent.push(peerNode); // push only enc
|
|
728
481
|
}
|
|
@@ -739,8 +492,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
739
492
|
tag: 'message',
|
|
740
493
|
attrs: {
|
|
741
494
|
id: msgId,
|
|
742
|
-
|
|
743
|
-
type: getMessageType(message),
|
|
495
|
+
type: isNewsletter ? getTypeMessage(message) : 'text',
|
|
744
496
|
...(additionalAttributes || {})
|
|
745
497
|
},
|
|
746
498
|
content: binaryNodeContent
|
|
@@ -749,11 +501,11 @@ export const makeMessagesSocket = (config) => {
|
|
|
749
501
|
// ensure the message is only sent to that person
|
|
750
502
|
// if a retry receipt is sent to everyone -- it'll fail decryption for everyone else who received the msg
|
|
751
503
|
if (participant) {
|
|
752
|
-
if (isJidGroup(destinationJid)) {
|
|
504
|
+
if ((0, WABinary_1.isJidGroup)(destinationJid)) {
|
|
753
505
|
stanza.attrs.to = destinationJid;
|
|
754
506
|
stanza.attrs.participant = participant.jid;
|
|
755
507
|
}
|
|
756
|
-
else if (areJidsSameUser(participant.jid, meId)) {
|
|
508
|
+
else if ((0, WABinary_1.areJidsSameUser)(participant.jid, meId)) {
|
|
757
509
|
stanza.attrs.to = participant.jid;
|
|
758
510
|
stanza.attrs.recipient = destinationJid;
|
|
759
511
|
}
|
|
@@ -765,149 +517,116 @@ export const makeMessagesSocket = (config) => {
|
|
|
765
517
|
stanza.attrs.to = destinationJid;
|
|
766
518
|
}
|
|
767
519
|
if (shouldIncludeDeviceIdentity) {
|
|
768
|
-
;
|
|
769
520
|
stanza.content.push({
|
|
770
521
|
tag: 'device-identity',
|
|
771
522
|
attrs: {},
|
|
772
|
-
content: encodeSignedDeviceIdentity(authState.creds.account, true)
|
|
523
|
+
content: (0, Utils_1.encodeSignedDeviceIdentity)(authState.creds.account, true)
|
|
773
524
|
});
|
|
774
525
|
logger.debug({ jid }, 'adding device identity');
|
|
775
526
|
}
|
|
776
|
-
if (
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
fromMe: true,
|
|
785
|
-
remoteJid: destinationJid,
|
|
786
|
-
participant: participant?.jid
|
|
787
|
-
};
|
|
788
|
-
const reportingNode = await getMessageReportingToken(encoded, reportingMessage, reportingKey);
|
|
789
|
-
if (reportingNode) {
|
|
790
|
-
;
|
|
791
|
-
stanza.content.push(reportingNode);
|
|
792
|
-
logger.trace({ jid }, 'added reporting token to message');
|
|
527
|
+
if (pollMessage || messages.eventMessage) {
|
|
528
|
+
let attrs = {};
|
|
529
|
+
if (messages.eventMessage) {
|
|
530
|
+
attrs.event_type = 'creation';
|
|
531
|
+
} else {
|
|
532
|
+
attrs.polltype = 'creation';
|
|
533
|
+
if (isNewsletter) {
|
|
534
|
+
attrs.contenttype = (pollMessage && pollMessage.pollContentType === 2) ? 'image' : 'text';
|
|
793
535
|
}
|
|
794
536
|
}
|
|
795
|
-
catch (error) {
|
|
796
|
-
logger.warn({ jid, trace: error?.stack }, 'failed to attach reporting token');
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
// WA Web never attaches tctoken to peer (AppStateSync) messages — server rejects with 479
|
|
800
|
-
const isPeerMessage = additionalAttributes?.['category'] === 'peer';
|
|
801
|
-
const is1on1Send = !isGroup && !isRetryResend && !isStatus && !isNewsletter && !isPeerMessage;
|
|
802
|
-
// Resolve destination to LID for tctoken storage — matches Signal session key pattern
|
|
803
|
-
const tcTokenJid = is1on1Send ? await resolveTcTokenJid(destinationJid, getLIDForPN) : destinationJid;
|
|
804
|
-
const contactTcTokenData = is1on1Send ? await authState.keys.get('tctoken', [tcTokenJid]) : {};
|
|
805
|
-
const existingTokenEntry = contactTcTokenData[tcTokenJid];
|
|
806
|
-
let tcTokenBuffer = existingTokenEntry?.token;
|
|
807
|
-
// Treat expired tokens the same as missing — clear from cache
|
|
808
|
-
if (tcTokenBuffer?.length && isTcTokenExpired(existingTokenEntry?.timestamp)) {
|
|
809
|
-
logger.debug({ jid: destinationJid, timestamp: existingTokenEntry?.timestamp }, 'tctoken expired, clearing');
|
|
810
|
-
tcTokenBuffer = undefined;
|
|
811
|
-
// Preserve senderTimestamp so the fire-and-forget issuance dedupe survives cleanup.
|
|
812
|
-
const cleared = existingTokenEntry?.senderTimestamp !== undefined
|
|
813
|
-
? { token: Buffer.alloc(0), senderTimestamp: existingTokenEntry.senderTimestamp }
|
|
814
|
-
: null;
|
|
815
|
-
try {
|
|
816
|
-
await authState.keys.set({ tctoken: { [tcTokenJid]: cleared } });
|
|
817
|
-
}
|
|
818
|
-
catch (err) {
|
|
819
|
-
logger.debug({ jid: destinationJid, err: err?.message }, 'failed to persist tctoken expiry cleanup');
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
if (tcTokenBuffer?.length && sock.serverProps.privacyTokenOn1to1) {
|
|
823
|
-
;
|
|
824
537
|
stanza.content.push({
|
|
825
|
-
tag: '
|
|
826
|
-
attrs:
|
|
827
|
-
content: tcTokenBuffer
|
|
538
|
+
tag: 'meta',
|
|
539
|
+
attrs: attrs
|
|
828
540
|
});
|
|
829
541
|
}
|
|
830
542
|
if (additionalNodes && additionalNodes.length > 0) {
|
|
831
|
-
;
|
|
832
543
|
stanza.content.push(...additionalNodes);
|
|
833
544
|
}
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
.
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
getLIDForPN
|
|
856
|
-
});
|
|
857
|
-
const currentData = await authState.keys.get('tctoken', [tcTokenJid]);
|
|
858
|
-
const currentEntry = currentData[tcTokenJid];
|
|
859
|
-
const indexWrite = await buildMergedTcTokenIndexWrite(authState.keys, [tcTokenJid]);
|
|
860
|
-
await authState.keys.set({
|
|
861
|
-
tctoken: {
|
|
862
|
-
[tcTokenJid]: {
|
|
863
|
-
token: Buffer.alloc(0),
|
|
864
|
-
...currentEntry,
|
|
865
|
-
senderTimestamp: issueTimestamp
|
|
545
|
+
if (AI && isPrivatee) {
|
|
546
|
+
const botNode = {
|
|
547
|
+
tag: 'bot',
|
|
548
|
+
attrs: {
|
|
549
|
+
biz_bot: '1'
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
stanza.content.push(botNode);
|
|
553
|
+
}
|
|
554
|
+
const content = (0, Utils_1.normalizeMessageContent)(message);
|
|
555
|
+
const contentType = (0, Utils_1.getContentType)(content);
|
|
556
|
+
if (((0, WABinary_1.isJidGroup)(jid) || (0, WABinary_1.isJidUser)(jid)) && (contentType === 'interactiveMessage' ||
|
|
557
|
+
contentType === 'buttonsMessage' ||
|
|
558
|
+
contentType === 'listMessage')) {
|
|
559
|
+
const bizNode = { tag: 'biz', attrs: {} };
|
|
560
|
+
if ((((_l = (_k = message === null || message === void 0 ? void 0 : message.viewOnceMessage) === null || _k === void 0 ? void 0 : _k.message) === null || _l === void 0 ? void 0 : _l.interactiveMessage) || ((_o = (_m = message === null || message === void 0 ? void 0 : message.viewOnceMessageV2) === null || _m === void 0 ? void 0 : _m.message) === null || _o === void 0 ? void 0 : _o.interactiveMessage) || ((_q = (_p = message === null || message === void 0 ? void 0 : message.viewOnceMessageV2Extension) === null || _p === void 0 ? void 0 : _p.message) === null || _q === void 0 ? void 0 : _q.interactiveMessage) || (message === null || message === void 0 ? void 0 : message.interactiveMessage)) || (((_s = (_r = message === null || message === void 0 ? void 0 : message.viewOnceMessage) === null || _r === void 0 ? void 0 : _r.message) === null || _s === void 0 ? void 0 : _s.buttonsMessage) || ((_u = (_t = message === null || message === void 0 ? void 0 : message.viewOnceMessageV2) === null || _t === void 0 ? void 0 : _t.message) === null || _u === void 0 ? void 0 : _u.buttonsMessage) || ((_w = (_v = message === null || message === void 0 ? void 0 : message.viewOnceMessageV2Extension) === null || _v === void 0 ? void 0 : _v.message) === null || _w === void 0 ? void 0 : _w.buttonsMessage) || (message === null || message === void 0 ? void 0 : message.buttonsMessage))) {
|
|
561
|
+
bizNode.content = [{
|
|
562
|
+
tag: 'interactive',
|
|
563
|
+
attrs: {
|
|
564
|
+
type: 'native_flow',
|
|
565
|
+
v: '1'
|
|
866
566
|
},
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
567
|
+
content: [{
|
|
568
|
+
tag: 'native_flow',
|
|
569
|
+
attrs: { v: '9', name: 'mixed' }
|
|
570
|
+
}]
|
|
571
|
+
}];
|
|
572
|
+
}
|
|
573
|
+
else if (message === null || message === void 0 ? void 0 : message.listMessage) {
|
|
574
|
+
// list message only support in private chat
|
|
575
|
+
bizNode.content = [{
|
|
576
|
+
tag: 'list',
|
|
577
|
+
attrs: {
|
|
578
|
+
type: 'product_list',
|
|
579
|
+
v: '2'
|
|
580
|
+
}
|
|
581
|
+
}];
|
|
582
|
+
}
|
|
583
|
+
stanza.content.push(bizNode);
|
|
881
584
|
}
|
|
882
|
-
|
|
585
|
+
logger.debug({ msgId }, `sending message to ${participants.length} devices`);
|
|
586
|
+
await sendNode(stanza);
|
|
587
|
+
});
|
|
883
588
|
return msgId;
|
|
884
589
|
};
|
|
885
|
-
const
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
if (
|
|
590
|
+
const getTypeMessage = (msg) => {
|
|
591
|
+
if (msg.viewOnceMessage) {
|
|
592
|
+
return getTypeMessage(msg.viewOnceMessage.message);
|
|
593
|
+
}
|
|
594
|
+
else if (msg.viewOnceMessageV2) {
|
|
595
|
+
return getTypeMessage(msg.viewOnceMessageV2.message);
|
|
596
|
+
}
|
|
597
|
+
else if (msg.viewOnceMessageV2Extension) {
|
|
598
|
+
return getTypeMessage(msg.viewOnceMessageV2Extension.message);
|
|
599
|
+
}
|
|
600
|
+
else if (msg.ephemeralMessage) {
|
|
601
|
+
return getTypeMessage(msg.ephemeralMessage.message);
|
|
602
|
+
}
|
|
603
|
+
else if (msg.documentWithCaptionMessage) {
|
|
604
|
+
return getTypeMessage(msg.documentWithCaptionMessage.message);
|
|
605
|
+
}
|
|
606
|
+
else if (msg.reactionMessage) {
|
|
890
607
|
return 'reaction';
|
|
891
608
|
}
|
|
892
|
-
if (
|
|
893
|
-
normalizedMessage.pollCreationMessageV2 ||
|
|
894
|
-
normalizedMessage.pollCreationMessageV3 ||
|
|
895
|
-
normalizedMessage.pollUpdateMessage) {
|
|
609
|
+
else if (msg.pollCreationMessage || msg.pollCreationMessageV2 || msg.pollCreationMessageV3 || msg.pollUpdateMessage) {
|
|
896
610
|
return 'poll';
|
|
897
611
|
}
|
|
898
|
-
if (
|
|
899
|
-
return 'event';
|
|
900
|
-
}
|
|
901
|
-
if (getMediaType(normalizedMessage) !== '') {
|
|
612
|
+
else if (getMediaType(msg)) {
|
|
902
613
|
return 'media';
|
|
903
614
|
}
|
|
904
|
-
|
|
615
|
+
else {
|
|
616
|
+
return 'text';
|
|
617
|
+
}
|
|
905
618
|
};
|
|
906
619
|
const getMediaType = (message) => {
|
|
907
620
|
if (message.imageMessage) {
|
|
908
621
|
return 'image';
|
|
909
622
|
}
|
|
623
|
+
else if (message.ptvMessage) {
|
|
624
|
+
return 'ptv';
|
|
625
|
+
}
|
|
910
626
|
else if (message.videoMessage) {
|
|
627
|
+
if (message.videoMessage.ptv) {
|
|
628
|
+
return 'ptv';
|
|
629
|
+
}
|
|
911
630
|
return message.videoMessage.gifPlayback ? 'gif' : 'video';
|
|
912
631
|
}
|
|
913
632
|
else if (message.audioMessage) {
|
|
@@ -946,17 +665,19 @@ export const makeMessagesSocket = (config) => {
|
|
|
946
665
|
else if (message.interactiveResponseMessage) {
|
|
947
666
|
return 'native_flow_response';
|
|
948
667
|
}
|
|
668
|
+
else if (message.richResponseMessage) {
|
|
669
|
+
return 'rich_response';
|
|
670
|
+
}
|
|
949
671
|
else if (message.groupInviteMessage) {
|
|
950
672
|
return 'url';
|
|
951
673
|
}
|
|
952
|
-
return '';
|
|
953
674
|
};
|
|
954
|
-
const
|
|
955
|
-
const t = (
|
|
675
|
+
const getPrivacyTokens = async (jids) => {
|
|
676
|
+
const t = (0, Utils_1.unixTimestampSeconds)().toString();
|
|
956
677
|
const result = await query({
|
|
957
678
|
tag: 'iq',
|
|
958
679
|
attrs: {
|
|
959
|
-
to: S_WHATSAPP_NET,
|
|
680
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
960
681
|
type: 'set',
|
|
961
682
|
xmlns: 'privacy'
|
|
962
683
|
},
|
|
@@ -967,7 +688,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
967
688
|
content: jids.map(jid => ({
|
|
968
689
|
tag: 'token',
|
|
969
690
|
attrs: {
|
|
970
|
-
jid: jidNormalizedUser(jid),
|
|
691
|
+
jid: (0, WABinary_1.jidNormalizedUser)(jid),
|
|
971
692
|
t,
|
|
972
693
|
type: 'trusted_contact'
|
|
973
694
|
}
|
|
@@ -977,42 +698,29 @@ export const makeMessagesSocket = (config) => {
|
|
|
977
698
|
});
|
|
978
699
|
return result;
|
|
979
700
|
};
|
|
980
|
-
const waUploadToServer = getWAUploadToServer(config, refreshMediaConn);
|
|
981
|
-
const
|
|
982
|
-
|
|
983
|
-
if (!config.userDevicesCache && userDevicesCache.close) {
|
|
984
|
-
userDevicesCache.close();
|
|
985
|
-
}
|
|
986
|
-
mediaConn = undefined;
|
|
987
|
-
if (messageRetryManager) {
|
|
988
|
-
messageRetryManager.clear();
|
|
989
|
-
}
|
|
990
|
-
});
|
|
701
|
+
const waUploadToServer = (0, Utils_1.getWAUploadToServer)(config, refreshMediaConn);
|
|
702
|
+
const avelinel = new aveline(Utils_1, waUploadToServer, relayMessage);
|
|
703
|
+
const waitForMsgMediaUpdate = (0, Utils_1.bindWaitForEvent)(ev, 'messages.media-update');
|
|
991
704
|
return {
|
|
992
705
|
...sock,
|
|
993
|
-
|
|
994
|
-
devicesMutex,
|
|
995
|
-
issuePrivacyTokens,
|
|
706
|
+
getPrivacyTokens,
|
|
996
707
|
assertSessions,
|
|
997
708
|
relayMessage,
|
|
998
709
|
sendReceipt,
|
|
999
710
|
sendReceipts,
|
|
711
|
+
avelinel,
|
|
1000
712
|
readMessages,
|
|
1001
713
|
refreshMediaConn,
|
|
1002
|
-
// Function (not getter) so the spread in chats.ts preserves the live closure binding.
|
|
1003
|
-
getMediaHost: () => mediaHost,
|
|
1004
714
|
waUploadToServer,
|
|
1005
715
|
fetchPrivacySettings,
|
|
1006
|
-
sendPeerDataOperationMessage,
|
|
1007
|
-
createParticipantNodes,
|
|
1008
716
|
getUSyncDevices,
|
|
1009
|
-
|
|
1010
|
-
|
|
717
|
+
createParticipantNodes,
|
|
718
|
+
sendPeerDataOperationMessage,
|
|
1011
719
|
updateMediaMessage: async (message) => {
|
|
1012
|
-
const content = assertMediaContent(message.message);
|
|
720
|
+
const content = (0, Utils_1.assertMediaContent)(message.message);
|
|
1013
721
|
const mediaKey = content.mediaKey;
|
|
1014
722
|
const meId = authState.creds.me.id;
|
|
1015
|
-
const node = encryptMediaRetryRequest(message.key, mediaKey, meId);
|
|
723
|
+
const node = await (0, Utils_1.encryptMediaRetryRequest)(message.key, mediaKey, meId);
|
|
1016
724
|
let error = undefined;
|
|
1017
725
|
await Promise.all([
|
|
1018
726
|
sendNode(node),
|
|
@@ -1024,16 +732,13 @@ export const makeMessagesSocket = (config) => {
|
|
|
1024
732
|
}
|
|
1025
733
|
else {
|
|
1026
734
|
try {
|
|
1027
|
-
const media = decryptMediaRetryData(result.media, mediaKey, result.key.id);
|
|
1028
|
-
if (media.result !== proto.MediaRetryNotification.ResultType.SUCCESS) {
|
|
1029
|
-
const resultStr = proto.MediaRetryNotification.ResultType[media.result];
|
|
1030
|
-
throw new Boom(`Media re-upload failed by device (${resultStr})`, {
|
|
1031
|
-
data: media,
|
|
1032
|
-
statusCode: getStatusCodeForMediaRetry(media.result) || 404
|
|
1033
|
-
});
|
|
735
|
+
const media = await (0, Utils_1.decryptMediaRetryData)(result.media, mediaKey, result.key.id);
|
|
736
|
+
if (media.result !== WAProto_1.proto.MediaRetryNotification.ResultType.SUCCESS) {
|
|
737
|
+
const resultStr = WAProto_1.proto.MediaRetryNotification.ResultType[media.result];
|
|
738
|
+
throw new boom_1.Boom(`Media re-upload failed by device (${resultStr})`, { data: media, statusCode: (0, Utils_1.getStatusCodeForMediaRetry)(media.result) || 404 });
|
|
1034
739
|
}
|
|
1035
740
|
content.directPath = media.directPath;
|
|
1036
|
-
content.url = getUrlFromDirectPath(content.directPath
|
|
741
|
+
content.url = (0, Utils_1.getUrlFromDirectPath)(content.directPath);
|
|
1037
742
|
logger.debug({ directPath: media.directPath, key: result.key }, 'media update successful');
|
|
1038
743
|
}
|
|
1039
744
|
catch (err) {
|
|
@@ -1047,94 +752,384 @@ export const makeMessagesSocket = (config) => {
|
|
|
1047
752
|
if (error) {
|
|
1048
753
|
throw error;
|
|
1049
754
|
}
|
|
1050
|
-
ev.emit('messages.update', [
|
|
755
|
+
ev.emit('messages.update', [
|
|
756
|
+
{ key: message.key, update: { message: message.message } }
|
|
757
|
+
]);
|
|
1051
758
|
return message;
|
|
1052
759
|
},
|
|
760
|
+
sendStatusMentions: async (content, jids = []) => {
|
|
761
|
+
const userJid = WABinary_1.jidNormalizedUser(authState.creds.me.id)
|
|
762
|
+
let allUsers = new Set()
|
|
763
|
+
allUsers.add(userJid)
|
|
764
|
+
|
|
765
|
+
for (const id of jids) {
|
|
766
|
+
const isGroup = WABinary_1.isJidGroup(id)
|
|
767
|
+
const isPrivate = WABinary_1.isJidUser(id)
|
|
768
|
+
|
|
769
|
+
if (isGroup) {
|
|
770
|
+
try {
|
|
771
|
+
const metadata = await cachedGroupMetadata(id) || await global.groupMetadataCache(id)
|
|
772
|
+
const participants = metadata.participants.map(p => WABinary_1.jidNormalizedUser(p.id))
|
|
773
|
+
participants.forEach(jid => allUsers.add(jid))
|
|
774
|
+
} catch (error) {
|
|
775
|
+
logger.error(`Error getting metadata for group ${id}: ${error}`)
|
|
776
|
+
}
|
|
777
|
+
} else if (isPrivate) {
|
|
778
|
+
allUsers.add(WABinary_1.jidNormalizedUser(id))
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
const uniqueUsers = Array.from(allUsers)
|
|
783
|
+
const getRandomHexColor = () => "#" + Math.floor(Math.random() * 16777215).toString(16).padStart(6, "0")
|
|
784
|
+
|
|
785
|
+
const isMedia = content.image || content.video || content.audio
|
|
786
|
+
const isAudio = !!content.audio
|
|
787
|
+
|
|
788
|
+
const messageContent = {
|
|
789
|
+
...content
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
if (isMedia && !isAudio) {
|
|
793
|
+
if (messageContent.text) {
|
|
794
|
+
messageContent.caption = messageContent.text
|
|
795
|
+
|
|
796
|
+
delete messageContent.text
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
delete messageContent.ptt
|
|
800
|
+
delete messageContent.font
|
|
801
|
+
delete messageContent.backgroundColor
|
|
802
|
+
delete messageContent.textColor
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
if (isAudio) {
|
|
806
|
+
delete messageContent.text
|
|
807
|
+
delete messageContent.caption
|
|
808
|
+
delete messageContent.font
|
|
809
|
+
delete messageContent.textColor
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
const font = !isMedia ? (content.font || Math.floor(Math.random() * 9)) : undefined
|
|
813
|
+
const textColor = !isMedia ? (content.textColor || getRandomHexColor()) : undefined
|
|
814
|
+
const backgroundColor = (!isMedia || isAudio) ? (content.backgroundColor || getRandomHexColor()) : undefined
|
|
815
|
+
const ptt = isAudio ? (typeof content.ptt === 'boolean' ? content.ptt : true) : undefined
|
|
816
|
+
|
|
817
|
+
let msg
|
|
818
|
+
let mediaHandle
|
|
819
|
+
try {
|
|
820
|
+
msg = await Utils_1.generateWAMessage(WABinary_1.STORIES_JID, messageContent, {
|
|
821
|
+
logger,
|
|
822
|
+
userJid,
|
|
823
|
+
getUrlInfo: text => link_preview_1.getUrlInfo(text, {
|
|
824
|
+
thumbnailWidth: linkPreviewImageThumbnailWidth,
|
|
825
|
+
fetchOpts: {
|
|
826
|
+
timeout: 3000,
|
|
827
|
+
...axiosOptions || {}
|
|
828
|
+
},
|
|
829
|
+
logger,
|
|
830
|
+
uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
|
|
831
|
+
}),
|
|
832
|
+
upload: async (encFilePath, opts) => {
|
|
833
|
+
const up = await waUploadToServer(encFilePath, {
|
|
834
|
+
...opts
|
|
835
|
+
})
|
|
836
|
+
mediaHandle = up.handle
|
|
837
|
+
return up
|
|
838
|
+
},
|
|
839
|
+
mediaCache: config.mediaCache,
|
|
840
|
+
options: config.options,
|
|
841
|
+
font,
|
|
842
|
+
textColor,
|
|
843
|
+
backgroundColor,
|
|
844
|
+
ptt
|
|
845
|
+
})
|
|
846
|
+
} catch (error) {
|
|
847
|
+
logger.error(`Error generating message: ${error}`)
|
|
848
|
+
throw error
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
await relayMessage(WABinary_1.STORIES_JID, msg.message, {
|
|
852
|
+
messageId: msg.key.id,
|
|
853
|
+
statusJidList: uniqueUsers,
|
|
854
|
+
additionalNodes: [{
|
|
855
|
+
tag: 'meta',
|
|
856
|
+
attrs: {},
|
|
857
|
+
content: [{
|
|
858
|
+
tag: 'mentioned_users',
|
|
859
|
+
attrs: {},
|
|
860
|
+
content: jids.map(jid => ({
|
|
861
|
+
tag: 'to',
|
|
862
|
+
attrs: {
|
|
863
|
+
jid: WABinary_1.jidNormalizedUser(jid)
|
|
864
|
+
}
|
|
865
|
+
}))
|
|
866
|
+
}]
|
|
867
|
+
}]
|
|
868
|
+
})
|
|
869
|
+
|
|
870
|
+
for (const id of jids) {
|
|
871
|
+
try {
|
|
872
|
+
const normalizedId = WABinary_1.jidNormalizedUser(id)
|
|
873
|
+
const isPrivate = WABinary_1.isJidUser(normalizedId)
|
|
874
|
+
const type = isPrivate ? 'statusMentionMessage' : 'groupStatusMentionMessage'
|
|
875
|
+
|
|
876
|
+
const protocolMessage = {
|
|
877
|
+
[type]: {
|
|
878
|
+
message: {
|
|
879
|
+
protocolMessage: {
|
|
880
|
+
key: msg.key,
|
|
881
|
+
type: 25
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
},
|
|
885
|
+
messageContextInfo: {
|
|
886
|
+
messageSecret: crypto_1.randomBytes(32)
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
const statusMsg = await Utils_1.generateWAMessageFromContent(normalizedId,
|
|
891
|
+
protocolMessage, {}
|
|
892
|
+
)
|
|
893
|
+
|
|
894
|
+
await relayMessage(
|
|
895
|
+
normalizedId,
|
|
896
|
+
statusMsg.message, {
|
|
897
|
+
additionalNodes: [{
|
|
898
|
+
tag: 'meta',
|
|
899
|
+
attrs: isPrivate ? {
|
|
900
|
+
is_status_mention: 'true'
|
|
901
|
+
} : {
|
|
902
|
+
is_group_status_mention: 'true'
|
|
903
|
+
}
|
|
904
|
+
}]
|
|
905
|
+
}
|
|
906
|
+
)
|
|
907
|
+
|
|
908
|
+
await Utils_1.delay(2000)
|
|
909
|
+
} catch (error) {
|
|
910
|
+
logger.error(`Error sending to ${id}: ${error}`)
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
return msg
|
|
915
|
+
},
|
|
1053
916
|
sendMessage: async (jid, content, options = {}) => {
|
|
917
|
+
var _a, _b, _c;
|
|
1054
918
|
const userJid = authState.creds.me.id;
|
|
919
|
+
const getParticipantAttr = () => filter ? { participant: { jid } } : {};
|
|
920
|
+
const { filter = false, quoted } = options;
|
|
921
|
+
const messageType = avelinel.detectType(content);
|
|
922
|
+
|
|
923
|
+
if (messageType) {
|
|
924
|
+
switch (messageType) {
|
|
925
|
+
case 'PAYMENT':
|
|
926
|
+
const paymentContent = await avelinel.handlePayment(content, quoted);
|
|
927
|
+
return await relayMessage(jid, paymentContent, {
|
|
928
|
+
messageId: Utils_1.generateMessageID(),
|
|
929
|
+
...getParticipantAttr()
|
|
930
|
+
});
|
|
931
|
+
|
|
932
|
+
case 'PRODUCT':
|
|
933
|
+
const productContent = await avelinel.handleProduct(content, jid, quoted);
|
|
934
|
+
const productMsg = await Utils_1.generateWAMessageFromContent(jid, productContent, { quoted });
|
|
935
|
+
return await relayMessage(jid, productMsg.message, {
|
|
936
|
+
messageId: productMsg.key.id,
|
|
937
|
+
...getParticipantAttr()
|
|
938
|
+
});
|
|
939
|
+
|
|
940
|
+
case 'INTERACTIVE':
|
|
941
|
+
const interactiveContent = await avelinel.handleInteractive(content, jid, quoted);
|
|
942
|
+
const interactiveMsg = await Utils_1.generateWAMessageFromContent(jid, interactiveContent, { quoted });
|
|
943
|
+
return await relayMessage(jid, interactiveMsg.message, {
|
|
944
|
+
messageId: interactiveMsg.key.id,
|
|
945
|
+
...getParticipantAttr()
|
|
946
|
+
});
|
|
947
|
+
|
|
948
|
+
case 'ALBUM':
|
|
949
|
+
const albumContent = await avelinel.handleAlbum(content, jid, quoted);
|
|
950
|
+
return albumContent;
|
|
951
|
+
|
|
952
|
+
case 'EVENT':
|
|
953
|
+
return await avelinel.handleEvent(content, jid, quoted);
|
|
954
|
+
|
|
955
|
+
case 'POLL_RESULT':
|
|
956
|
+
return await avelinel.handlePollResult(content, jid, quoted);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
if (!options.ephemeralExpiration) {
|
|
961
|
+
if ((0, WABinary_1.isJidGroup)(jid)) {
|
|
962
|
+
const groups = await sock.groupQuery(jid, 'get', [{
|
|
963
|
+
tag: 'query',
|
|
964
|
+
attrs: {
|
|
965
|
+
request: 'interactive'
|
|
966
|
+
}
|
|
967
|
+
}]);
|
|
968
|
+
const metadata = (0, WABinary_1.getBinaryNodeChild)(groups, 'group');
|
|
969
|
+
const expiration = ((_b = (_a = (0, WABinary_1.getBinaryNodeChild)(metadata, 'ephemeral')) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b.expiration) || 0;
|
|
970
|
+
options.ephemeralExpiration = expiration;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
|
|
1055
974
|
if (typeof content === 'object' &&
|
|
1056
975
|
'disappearingMessagesInChat' in content &&
|
|
1057
976
|
typeof content['disappearingMessagesInChat'] !== 'undefined' &&
|
|
1058
|
-
isJidGroup(jid)) {
|
|
977
|
+
(0, WABinary_1.isJidGroup)(jid)) {
|
|
1059
978
|
const { disappearingMessagesInChat } = content;
|
|
1060
|
-
const value = typeof disappearingMessagesInChat === 'boolean'
|
|
1061
|
-
?
|
|
1062
|
-
|
|
1063
|
-
: 0
|
|
1064
|
-
: disappearingMessagesInChat;
|
|
979
|
+
const value = typeof disappearingMessagesInChat === 'boolean' ?
|
|
980
|
+
(disappearingMessagesInChat ? Defaults_1.WA_DEFAULT_EPHEMERAL : 0) :
|
|
981
|
+
disappearingMessagesInChat;
|
|
1065
982
|
await groupToggleEphemeral(jid, value);
|
|
1066
983
|
}
|
|
984
|
+
if (typeof content === 'object' && 'album' in content && content.album) {
|
|
985
|
+
const { album, caption } = content;
|
|
986
|
+
if (caption && !album[0].caption) {
|
|
987
|
+
album[0].caption = caption;
|
|
988
|
+
}
|
|
989
|
+
let mediaHandle;
|
|
990
|
+
let mediaMsg;
|
|
991
|
+
const albumMsg = (0, Utils_1.generateWAMessageFromContent)(jid, {
|
|
992
|
+
albumMessage: {
|
|
993
|
+
expectedImageCount: album.filter(item => 'image' in item).length,
|
|
994
|
+
expectedVideoCount: album.filter(item => 'video' in item).length
|
|
995
|
+
}
|
|
996
|
+
}, { userJid, ...options });
|
|
997
|
+
await relayMessage(jid, albumMsg.message, {
|
|
998
|
+
messageId: albumMsg.key.id
|
|
999
|
+
});
|
|
1000
|
+
for (const i in album) {
|
|
1001
|
+
const media = album[i];
|
|
1002
|
+
if ('image' in media) {
|
|
1003
|
+
mediaMsg = await (0, Utils_1.generateWAMessage)(jid, {
|
|
1004
|
+
image: media.image,
|
|
1005
|
+
...(media.caption ? { caption: media.caption } : {}),
|
|
1006
|
+
...options
|
|
1007
|
+
}, {
|
|
1008
|
+
userJid,
|
|
1009
|
+
upload: async (readStream, opts) => {
|
|
1010
|
+
const up = await waUploadToServer(readStream, { ...opts, newsletter: (0, WABinary_1.isJidNewsletter)(jid) });
|
|
1011
|
+
mediaHandle = up.handle;
|
|
1012
|
+
return up;
|
|
1013
|
+
},
|
|
1014
|
+
...options,
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
else if ('video' in media) {
|
|
1018
|
+
mediaMsg = await (0, Utils_1.generateWAMessage)(jid, {
|
|
1019
|
+
video: media.video,
|
|
1020
|
+
...(media.caption ? { caption: media.caption } : {}),
|
|
1021
|
+
...(media.gifPlayback !== undefined ? { gifPlayback: media.gifPlayback } : {}),
|
|
1022
|
+
...options
|
|
1023
|
+
}, {
|
|
1024
|
+
userJid,
|
|
1025
|
+
upload: async (readStream, opts) => {
|
|
1026
|
+
const up = await waUploadToServer(readStream, { ...opts, newsletter: (0, WABinary_1.isJidNewsletter)(jid) });
|
|
1027
|
+
mediaHandle = up.handle;
|
|
1028
|
+
return up;
|
|
1029
|
+
},
|
|
1030
|
+
...options,
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
1033
|
+
if (mediaMsg) {
|
|
1034
|
+
mediaMsg.message.messageContextInfo = {
|
|
1035
|
+
messageSecret: (0, crypto_1.randomBytes)(32),
|
|
1036
|
+
messageAssociation: {
|
|
1037
|
+
associationType: 1,
|
|
1038
|
+
parentMessageKey: albumMsg.key
|
|
1039
|
+
}
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1042
|
+
await relayMessage(jid, mediaMsg.message, {
|
|
1043
|
+
messageId: mediaMsg.key.id
|
|
1044
|
+
});
|
|
1045
|
+
await new Promise(resolve => setTimeout(resolve, 800));
|
|
1046
|
+
}
|
|
1047
|
+
return albumMsg;
|
|
1048
|
+
}
|
|
1067
1049
|
else {
|
|
1068
|
-
|
|
1050
|
+
let mediaHandle;
|
|
1051
|
+
const fullMsg = await (0, Utils_1.generateWAMessage)(jid, content, {
|
|
1069
1052
|
logger,
|
|
1070
1053
|
userJid,
|
|
1071
|
-
getUrlInfo: text => getUrlInfo(text, {
|
|
1054
|
+
getUrlInfo: text => (0, link_preview_1.getUrlInfo)(text, {
|
|
1072
1055
|
thumbnailWidth: linkPreviewImageThumbnailWidth,
|
|
1073
1056
|
fetchOpts: {
|
|
1074
1057
|
timeout: 3000,
|
|
1075
|
-
...
|
|
1058
|
+
...axiosOptions || {}
|
|
1076
1059
|
},
|
|
1077
1060
|
logger,
|
|
1078
|
-
uploadImage: generateHighQualityLinkPreview
|
|
1061
|
+
uploadImage: generateHighQualityLinkPreview
|
|
1062
|
+
? waUploadToServer
|
|
1063
|
+
: undefined
|
|
1079
1064
|
}),
|
|
1080
|
-
//TODO: CACHE
|
|
1081
1065
|
getProfilePicUrl: sock.profilePictureUrl,
|
|
1082
|
-
|
|
1083
|
-
|
|
1066
|
+
upload: async (readStream, opts) => {
|
|
1067
|
+
const up = await waUploadToServer(readStream, { ...opts, newsletter: (0, WABinary_1.isJidNewsletter)(jid) });
|
|
1068
|
+
mediaHandle = up.handle;
|
|
1069
|
+
return up;
|
|
1070
|
+
},
|
|
1084
1071
|
mediaCache: config.mediaCache,
|
|
1085
1072
|
options: config.options,
|
|
1086
|
-
messageId: generateMessageIDV2(sock.user
|
|
1087
|
-
...options
|
|
1073
|
+
messageId: (0, Utils_1.generateMessageIDV2)((_c = sock.user) === null || _c === void 0 ? void 0 : _c.id),
|
|
1074
|
+
...options,
|
|
1088
1075
|
});
|
|
1089
|
-
const isEventMsg = 'event' in content && !!content.event;
|
|
1090
1076
|
const isDeleteMsg = 'delete' in content && !!content.delete;
|
|
1091
1077
|
const isEditMsg = 'edit' in content && !!content.edit;
|
|
1092
1078
|
const isPinMsg = 'pin' in content && !!content.pin;
|
|
1079
|
+
const isKeepMsg = 'keep' in content && content.keep;
|
|
1093
1080
|
const isPollMessage = 'poll' in content && !!content.poll;
|
|
1081
|
+
const isAiMsg = 'ai' in content && !!content.ai;
|
|
1094
1082
|
const additionalAttributes = {};
|
|
1095
1083
|
const additionalNodes = [];
|
|
1096
1084
|
// required for delete
|
|
1097
1085
|
if (isDeleteMsg) {
|
|
1098
1086
|
// if the chat is a group, and I am not the author, then delete the message as an admin
|
|
1099
|
-
if (isJidGroup(content.delete
|
|
1087
|
+
if (((0, WABinary_1.isJidGroup)(content.delete.remoteJid) && !content.delete.fromMe) || (0, WABinary_1.isJidNewsletter)(jid)) {
|
|
1100
1088
|
additionalAttributes.edit = '8';
|
|
1101
1089
|
}
|
|
1102
1090
|
else {
|
|
1103
1091
|
additionalAttributes.edit = '7';
|
|
1104
1092
|
}
|
|
1093
|
+
// required for edit message
|
|
1105
1094
|
}
|
|
1106
1095
|
else if (isEditMsg) {
|
|
1107
|
-
additionalAttributes.edit = '1';
|
|
1096
|
+
additionalAttributes.edit = (0, WABinary_1.isJidNewsletter)(jid) ? '3' : '1';
|
|
1097
|
+
// required for pin message
|
|
1108
1098
|
}
|
|
1109
1099
|
else if (isPinMsg) {
|
|
1110
1100
|
additionalAttributes.edit = '2';
|
|
1101
|
+
// required for keep message
|
|
1102
|
+
}
|
|
1103
|
+
else if (isKeepMsg) {
|
|
1104
|
+
additionalAttributes.edit = '6';
|
|
1105
|
+
// required for polling message
|
|
1111
1106
|
}
|
|
1112
1107
|
else if (isPollMessage) {
|
|
1113
1108
|
additionalNodes.push({
|
|
1114
1109
|
tag: 'meta',
|
|
1115
1110
|
attrs: {
|
|
1116
1111
|
polltype: 'creation'
|
|
1117
|
-
}
|
|
1112
|
+
},
|
|
1118
1113
|
});
|
|
1114
|
+
// required to display AI icon on message
|
|
1119
1115
|
}
|
|
1120
|
-
else if (
|
|
1116
|
+
else if (isAiMsg) {
|
|
1121
1117
|
additionalNodes.push({
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
}
|
|
1126
|
-
});
|
|
1127
|
-
}
|
|
1128
|
-
await relayMessage(jid, fullMsg.message, {
|
|
1129
|
-
messageId: fullMsg.key.id,
|
|
1130
|
-
useCachedGroupMetadata: options.useCachedGroupMetadata,
|
|
1131
|
-
additionalAttributes,
|
|
1132
|
-
statusJidList: options.statusJidList,
|
|
1133
|
-
additionalNodes
|
|
1118
|
+
attrs: {
|
|
1119
|
+
biz_bot: '1'
|
|
1120
|
+
}, tag: "bot"
|
|
1134
1121
|
});
|
|
1122
|
+
}
|
|
1123
|
+
if (mediaHandle) {
|
|
1124
|
+
additionalAttributes['media_id'] = mediaHandle;
|
|
1125
|
+
}
|
|
1126
|
+
if ('cachedGroupMetadata' in options) {
|
|
1127
|
+
console.warn('cachedGroupMetadata in sendMessage are deprecated, now cachedGroupMetadata is part of the socket config.');
|
|
1128
|
+
}
|
|
1129
|
+
await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id, useCachedGroupMetadata: options.useCachedGroupMetadata, additionalAttributes, additionalNodes: isAiMsg ? additionalNodes : options.additionalNodes, statusJidList: options.statusJidList });
|
|
1135
1130
|
if (config.emitOwnEvents) {
|
|
1136
|
-
process.nextTick(
|
|
1137
|
-
|
|
1131
|
+
process.nextTick(() => {
|
|
1132
|
+
processingMutex.mutex(() => (upsertMessage(fullMsg, 'append')));
|
|
1138
1133
|
});
|
|
1139
1134
|
}
|
|
1140
1135
|
return fullMsg;
|
|
@@ -1142,4 +1137,4 @@ export const makeMessagesSocket = (config) => {
|
|
|
1142
1137
|
}
|
|
1143
1138
|
};
|
|
1144
1139
|
};
|
|
1145
|
-
|
|
1140
|
+
exports.makeMessagesSocket = makeMessagesSocket;
|