Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jajbshjahavahh
GitHub Repository: jajbshjahavahh/Gojo-Satoru
Path: blob/master/node_modules/@adiwajshing/baileys/lib/Socket/messages-send.js
2593 views
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
const node_cache_1 = __importDefault(require("node-cache"));
8
const WAProto_1 = require("../../WAProto");
9
const Defaults_1 = require("../Defaults");
10
const Utils_1 = require("../Utils");
11
const WABinary_1 = require("../WABinary");
12
const groups_1 = require("./groups");
13
const makeMessagesSocket = (config) => {
14
const { logger } = config;
15
const sock = groups_1.makeGroupsSocket(config);
16
const { ev, authState, query, generateMessageTag, sendNode, groupMetadata, groupToggleEphemeral } = sock;
17
const userDevicesCache = config.userDevicesCache || new node_cache_1.default({
18
stdTTL: 300,
19
useClones: false
20
});
21
let privacySettings;
22
const fetchPrivacySettings = async (force = false) => {
23
if (!privacySettings || force) {
24
const { content } = await query({
25
tag: 'iq',
26
attrs: {
27
xmlns: 'privacy',
28
to: WABinary_1.S_WHATSAPP_NET,
29
type: 'get'
30
},
31
content: [
32
{ tag: 'privacy', attrs: {} }
33
]
34
});
35
privacySettings = WABinary_1.reduceBinaryNodeToDictionary(content[0], 'category');
36
}
37
return privacySettings;
38
};
39
let mediaConn;
40
const refreshMediaConn = async (forceGet = false) => {
41
const media = await mediaConn;
42
if (!media || forceGet || (new Date().getTime() - media.fetchDate.getTime()) > media.ttl * 1000) {
43
mediaConn = (async () => {
44
const result = await query({
45
tag: 'iq',
46
attrs: {
47
type: 'set',
48
xmlns: 'w:m',
49
to: WABinary_1.S_WHATSAPP_NET,
50
},
51
content: [{ tag: 'media_conn', attrs: {} }]
52
});
53
const mediaConnNode = WABinary_1.getBinaryNodeChild(result, 'media_conn');
54
const node = {
55
hosts: WABinary_1.getBinaryNodeChildren(mediaConnNode, 'host').map(item => item.attrs),
56
auth: mediaConnNode.attrs.auth,
57
ttl: +mediaConnNode.attrs.ttl,
58
fetchDate: new Date()
59
};
60
logger.debug('fetched media conn');
61
return node;
62
})();
63
}
64
return mediaConn;
65
};
66
/**
67
* generic send receipt function
68
* used for receipts of phone call, read, delivery etc.
69
* */
70
const sendReceipt = async (jid, participant, messageIds, type) => {
71
const node = {
72
tag: 'receipt',
73
attrs: {
74
id: messageIds[0],
75
t: Date.now().toString(),
76
to: jid,
77
},
78
};
79
if (type) {
80
node.attrs.type = type;
81
}
82
if (participant) {
83
node.attrs.participant = participant;
84
}
85
const remainingMessageIds = messageIds.slice(1);
86
if (remainingMessageIds.length) {
87
node.content = [
88
{
89
tag: 'list',
90
attrs: {},
91
content: remainingMessageIds.map(id => ({
92
tag: 'item',
93
attrs: { id }
94
}))
95
}
96
];
97
}
98
logger.debug({ jid, messageIds, type }, 'sending receipt for messages');
99
await sendNode(node);
100
};
101
const sendReadReceipt = async (jid, participant, messageIds) => {
102
const privacySettings = await fetchPrivacySettings();
103
// based on privacy settings, we have to change the read type
104
const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self';
105
return sendReceipt(jid, participant, messageIds, readType);
106
};
107
const getUSyncDevices = async (jids, ignoreZeroDevices) => {
108
const deviceResults = [];
109
const users = [];
110
jids = Array.from(new Set(jids));
111
for (let jid of jids) {
112
const user = WABinary_1.jidDecode(jid).user;
113
jid = WABinary_1.jidNormalizedUser(jid);
114
if (userDevicesCache.has(user)) {
115
const devices = userDevicesCache.get(user);
116
deviceResults.push(...devices);
117
logger.trace({ user }, 'using cache for devices');
118
}
119
else {
120
users.push({ tag: 'user', attrs: { jid } });
121
}
122
}
123
const iq = {
124
tag: 'iq',
125
attrs: {
126
to: WABinary_1.S_WHATSAPP_NET,
127
type: 'get',
128
xmlns: 'usync',
129
},
130
content: [
131
{
132
tag: 'usync',
133
attrs: {
134
sid: generateMessageTag(),
135
mode: 'query',
136
last: 'true',
137
index: '0',
138
context: 'message',
139
},
140
content: [
141
{
142
tag: 'query',
143
attrs: {},
144
content: [
145
{
146
tag: 'devices',
147
attrs: { version: '2' }
148
}
149
]
150
},
151
{ tag: 'list', attrs: {}, content: users }
152
]
153
},
154
],
155
};
156
const result = await query(iq);
157
const extracted = Utils_1.extractDeviceJids(result, authState.creds.me.id, ignoreZeroDevices);
158
const deviceMap = {};
159
for (const item of extracted) {
160
deviceMap[item.user] = deviceMap[item.user] || [];
161
deviceMap[item.user].push(item);
162
deviceResults.push(item);
163
}
164
for (const key in deviceMap) {
165
userDevicesCache.set(key, deviceMap[key]);
166
}
167
return deviceResults;
168
};
169
const assertSessions = async (jids, force) => {
170
let jidsRequiringFetch = [];
171
if (force) {
172
jidsRequiringFetch = jids;
173
}
174
else {
175
const addrs = jids.map(jid => Utils_1.jidToSignalProtocolAddress(jid).toString());
176
const sessions = await authState.keys.get('session', addrs);
177
for (const jid of jids) {
178
const signalId = Utils_1.jidToSignalProtocolAddress(jid).toString();
179
if (!sessions[signalId]) {
180
jidsRequiringFetch.push(jid);
181
}
182
}
183
}
184
if (jidsRequiringFetch.length) {
185
logger.debug({ jidsRequiringFetch }, 'fetching sessions');
186
const result = await query({
187
tag: 'iq',
188
attrs: {
189
xmlns: 'encrypt',
190
type: 'get',
191
to: WABinary_1.S_WHATSAPP_NET,
192
},
193
content: [
194
{
195
tag: 'key',
196
attrs: {},
197
content: jidsRequiringFetch.map(jid => ({
198
tag: 'user',
199
attrs: { jid, reason: 'identity' },
200
}))
201
}
202
]
203
});
204
await Utils_1.parseAndInjectE2ESessions(result, authState);
205
return true;
206
}
207
return false;
208
};
209
const createParticipantNodes = async (jids, bytes) => {
210
await assertSessions(jids, false);
211
if (authState.keys.isInTransaction()) {
212
await authState.keys.prefetch('session', jids.map(jid => Utils_1.jidToSignalProtocolAddress(jid).toString()));
213
}
214
const nodes = await Promise.all(jids.map(async (jid) => {
215
const { type, ciphertext } = await Utils_1.encryptSignalProto(jid, bytes, authState);
216
const node = {
217
tag: 'to',
218
attrs: { jid },
219
content: [{
220
tag: 'enc',
221
attrs: { v: '2', type },
222
content: ciphertext
223
}]
224
};
225
return node;
226
}));
227
return nodes;
228
};
229
const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, cachedGroupMetadata }) => {
230
const meId = authState.creds.me.id;
231
const { user, server } = WABinary_1.jidDecode(jid);
232
const isGroup = server === 'g.us';
233
msgId = msgId || Utils_1.generateMessageID();
234
const encodedMsg = Utils_1.encodeWAMessage(message);
235
const participants = [];
236
const destinationJid = WABinary_1.jidEncode(user, isGroup ? 'g.us' : 's.whatsapp.net');
237
const binaryNodeContent = [];
238
const devices = [];
239
if (participant) {
240
const { user, device } = WABinary_1.jidDecode(participant);
241
devices.push({ user, device });
242
}
243
await authState.keys.transaction(async () => {
244
if (isGroup) {
245
const { ciphertext, senderKeyDistributionMessageKey } = await Utils_1.encryptSenderKeyMsgSignalProto(destinationJid, encodedMsg, meId, authState);
246
const [groupData, senderKeyMap] = await Promise.all([
247
(async () => {
248
let groupData = cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined;
249
if (!groupData) {
250
groupData = await groupMetadata(jid);
251
}
252
return groupData;
253
})(),
254
(async () => {
255
const result = await authState.keys.get('sender-key-memory', [jid]);
256
return result[jid] || {};
257
})()
258
]);
259
if (!participant) {
260
const participantsList = groupData.participants.map(p => p.id);
261
const additionalDevices = await getUSyncDevices(participantsList, false);
262
devices.push(...additionalDevices);
263
}
264
const senderKeyJids = [];
265
// ensure a connection is established with every device
266
for (const { user, device } of devices) {
267
const jid = WABinary_1.jidEncode(user, 's.whatsapp.net', device);
268
if (!senderKeyMap[jid]) {
269
senderKeyJids.push(jid);
270
// store that this person has had the sender keys sent to them
271
senderKeyMap[jid] = true;
272
}
273
}
274
// if there are some participants with whom the session has not been established
275
// if there are, we re-send the senderkey
276
if (senderKeyJids.length) {
277
logger.debug({ senderKeyJids }, 'sending new sender key');
278
const encSenderKeyMsg = Utils_1.encodeWAMessage({
279
senderKeyDistributionMessage: {
280
axolotlSenderKeyDistributionMessage: senderKeyDistributionMessageKey,
281
groupId: destinationJid
282
}
283
});
284
participants.push(...(await createParticipantNodes(senderKeyJids, encSenderKeyMsg)));
285
}
286
binaryNodeContent.push({
287
tag: 'enc',
288
attrs: { v: '2', type: 'skmsg' },
289
content: ciphertext
290
});
291
await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } });
292
}
293
else {
294
const { user: meUser } = WABinary_1.jidDecode(meId);
295
const encodedMeMsg = Utils_1.encodeWAMessage({
296
deviceSentMessage: {
297
destinationJid,
298
message
299
}
300
});
301
if (!participant) {
302
devices.push({ user });
303
devices.push({ user: meUser });
304
const additionalDevices = await getUSyncDevices([meId, jid], true);
305
devices.push(...additionalDevices);
306
}
307
const meJids = [];
308
const otherJids = [];
309
for (const { user, device } of devices) {
310
const jid = WABinary_1.jidEncode(user, 's.whatsapp.net', device);
311
const isMe = user === meUser;
312
if (isMe) {
313
meJids.push(jid);
314
}
315
else {
316
otherJids.push(jid);
317
}
318
}
319
const [meNodes, otherNodes] = await Promise.all([
320
createParticipantNodes(meJids, encodedMeMsg),
321
createParticipantNodes(otherJids, encodedMsg)
322
]);
323
participants.push(...meNodes);
324
participants.push(...otherNodes);
325
}
326
if (participants.length) {
327
binaryNodeContent.push({
328
tag: 'participants',
329
attrs: {},
330
content: participants
331
});
332
}
333
const stanza = {
334
tag: 'message',
335
attrs: {
336
id: msgId,
337
type: 'text',
338
to: destinationJid,
339
...(additionalAttributes || {})
340
},
341
content: binaryNodeContent
342
};
343
const shouldHaveIdentity = !!participants.find(participant => participant.content.find(n => n.attrs.type === 'pkmsg'));
344
if (shouldHaveIdentity) {
345
stanza.content.push({
346
tag: 'device-identity',
347
attrs: {},
348
content: WAProto_1.proto.ADVSignedDeviceIdentity.encode(authState.creds.account).finish()
349
});
350
logger.debug({ jid }, 'adding device identity');
351
}
352
logger.debug({ msgId }, `sending message to ${participants.length} devices`);
353
await sendNode(stanza);
354
});
355
return msgId;
356
};
357
const waUploadToServer = Utils_1.getWAUploadToServer(config, refreshMediaConn);
358
return {
359
...sock,
360
assertSessions,
361
relayMessage,
362
sendReceipt,
363
sendReadReceipt,
364
refreshMediaConn,
365
waUploadToServer,
366
fetchPrivacySettings,
367
sendMessage: async (jid, content, options = {}) => {
368
const userJid = authState.creds.me.id;
369
if (typeof content === 'object' &&
370
'disappearingMessagesInChat' in content &&
371
typeof content['disappearingMessagesInChat'] !== 'undefined' &&
372
WABinary_1.isJidGroup(jid)) {
373
const { disappearingMessagesInChat } = content;
374
const value = typeof disappearingMessagesInChat === 'boolean' ?
375
(disappearingMessagesInChat ? Defaults_1.WA_DEFAULT_EPHEMERAL : 0) :
376
disappearingMessagesInChat;
377
await groupToggleEphemeral(jid, value);
378
}
379
else {
380
const fullMsg = await Utils_1.generateWAMessage(jid, content, {
381
logger,
382
userJid,
383
// multi-device does not have this yet
384
//getUrlInfo: generateUrlInfo,
385
upload: waUploadToServer,
386
mediaCache: config.mediaCache,
387
...options,
388
});
389
const isDeleteMsg = 'delete' in content && !!content.delete;
390
const additionalAttributes = {};
391
// required for delete
392
if (isDeleteMsg) {
393
additionalAttributes.edit = '7';
394
}
395
await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id, additionalAttributes });
396
if (config.emitOwnEvents) {
397
process.nextTick(() => {
398
ev.emit('messages.upsert', { messages: [fullMsg], type: 'append' });
399
});
400
}
401
return fullMsg;
402
}
403
}
404
};
405
};
406
exports.makeMessagesSocket = makeMessagesSocket;
407
408