Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jajbshjahavahh
GitHub Repository: jajbshjahavahh/Gojo-Satoru
Path: blob/master/node_modules/@adiwajshing/baileys/lib/LegacySocket/chats.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
const Types_1 = require("../Types");
7
const generics_1 = require("../Utils/generics");
8
const WABinary_1 = require("../WABinary");
9
const auth_1 = __importDefault(require("./auth"));
10
const makeChatsSocket = (config) => {
11
const { logger } = config;
12
const sock = auth_1.default(config);
13
const { ev, ws: socketEvents, currentEpoch, setQuery, query, sendNode, state } = sock;
14
const chatsDebounceTimeout = generics_1.debouncedTimeout(10000, () => sendChatsQuery(1));
15
const sendChatsQuery = (epoch) => (sendNode({
16
json: {
17
tag: 'query',
18
attrs: { type: 'chat', epoch: epoch.toString() }
19
},
20
binaryTag: [Types_1.WAMetric.queryChat, Types_1.WAFlag.ignore]
21
}));
22
const profilePictureUrl = async (jid, timeoutMs) => {
23
const response = await query({
24
json: ['query', 'ProfilePicThumb', jid],
25
expect200: false,
26
requiresPhoneConnection: false,
27
timeoutMs
28
});
29
return response.eurl;
30
};
31
const executeChatModification = (node) => {
32
const { attrs: attributes } = node;
33
const updateType = attributes.type;
34
const jid = WABinary_1.jidNormalizedUser(attributes === null || attributes === void 0 ? void 0 : attributes.jid);
35
switch (updateType) {
36
case 'delete':
37
ev.emit('chats.delete', [jid]);
38
break;
39
case 'clear':
40
if (node.content) {
41
const ids = node.content.map(({ attrs }) => attrs.index);
42
ev.emit('messages.delete', { keys: ids.map(id => ({ id, remoteJid: jid })) });
43
}
44
else {
45
ev.emit('messages.delete', { jid, all: true });
46
}
47
break;
48
case 'archive':
49
ev.emit('chats.update', [{ id: jid, archive: true }]);
50
break;
51
case 'unarchive':
52
ev.emit('chats.update', [{ id: jid, archive: false }]);
53
break;
54
case 'pin':
55
ev.emit('chats.update', [{ id: jid, pin: attributes.pin ? +attributes.pin : null }]);
56
break;
57
case 'star':
58
case 'unstar':
59
const starred = updateType === 'star';
60
const updates = node.content.map(({ attrs }) => ({
61
key: {
62
remoteJid: jid,
63
id: attrs.index,
64
fromMe: attrs.owner === 'true'
65
},
66
update: { starred }
67
}));
68
ev.emit('messages.update', updates);
69
break;
70
case 'mute':
71
if (attributes.mute === '0') {
72
ev.emit('chats.update', [{ id: jid, mute: null }]);
73
}
74
else {
75
ev.emit('chats.update', [{ id: jid, mute: +attributes.mute }]);
76
}
77
break;
78
default:
79
logger.warn({ node }, 'received unrecognized chat update');
80
break;
81
}
82
};
83
const applyingPresenceUpdate = (update) => {
84
const id = WABinary_1.jidNormalizedUser(update.id);
85
const participant = WABinary_1.jidNormalizedUser(update.participant || update.id);
86
const presence = {
87
lastSeen: update.t ? +update.t : undefined,
88
lastKnownPresence: update.type
89
};
90
return { id, presences: { [participant]: presence } };
91
};
92
const chatRead = async (fromMessage, count) => {
93
await setQuery([
94
{
95
tag: 'read',
96
attrs: {
97
jid: fromMessage.remoteJid,
98
count: count.toString(),
99
index: fromMessage.id,
100
owner: fromMessage.fromMe ? 'true' : 'false'
101
}
102
}
103
], [Types_1.WAMetric.read, Types_1.WAFlag.ignore]);
104
if (config.emitOwnEvents) {
105
ev.emit('chats.update', [{ id: fromMessage.remoteJid, unreadCount: count < 0 ? -1 : 0 }]);
106
}
107
};
108
ev.on('connection.update', async ({ connection }) => {
109
if (connection !== 'open') {
110
return;
111
}
112
try {
113
await Promise.all([
114
sendNode({
115
json: { tag: 'query', attrs: { type: 'contacts', epoch: '1' } },
116
binaryTag: [Types_1.WAMetric.queryContact, Types_1.WAFlag.ignore]
117
}),
118
sendNode({
119
json: { tag: 'query', attrs: { type: 'status', epoch: '1' } },
120
binaryTag: [Types_1.WAMetric.queryStatus, Types_1.WAFlag.ignore]
121
}),
122
sendNode({
123
json: { tag: 'query', attrs: { type: 'quick_reply', epoch: '1' } },
124
binaryTag: [Types_1.WAMetric.queryQuickReply, Types_1.WAFlag.ignore]
125
}),
126
sendNode({
127
json: { tag: 'query', attrs: { type: 'label', epoch: '1' } },
128
binaryTag: [Types_1.WAMetric.queryLabel, Types_1.WAFlag.ignore]
129
}),
130
sendNode({
131
json: { tag: 'query', attrs: { type: 'emoji', epoch: '1' } },
132
binaryTag: [Types_1.WAMetric.queryEmoji, Types_1.WAFlag.ignore]
133
}),
134
sendNode({
135
json: {
136
tag: 'action',
137
attrs: { type: 'set', epoch: '1' },
138
content: [
139
{ tag: 'presence', attrs: { type: 'available' } }
140
]
141
},
142
binaryTag: [Types_1.WAMetric.presence, Types_1.WAFlag.available]
143
})
144
]);
145
chatsDebounceTimeout.start();
146
logger.debug('sent init queries');
147
}
148
catch (error) {
149
logger.error(`error in sending init queries: ${error}`);
150
}
151
});
152
socketEvents.on('CB:response,type:chat', async ({ content: data }) => {
153
chatsDebounceTimeout.cancel();
154
if (Array.isArray(data)) {
155
const contacts = [];
156
const chats = data.map(({ attrs }) => {
157
const id = WABinary_1.jidNormalizedUser(attrs.jid);
158
if (attrs.name) {
159
contacts.push({ id, name: attrs.name });
160
}
161
return {
162
id: WABinary_1.jidNormalizedUser(attrs.jid),
163
conversationTimestamp: attrs.t ? +attrs.t : undefined,
164
unreadCount: +attrs.count,
165
archive: attrs.archive === 'true' ? true : undefined,
166
pin: attrs.pin ? +attrs.pin : undefined,
167
mute: attrs.mute ? +attrs.mute : undefined,
168
notSpam: !(attrs.spam === 'true'),
169
name: attrs.name,
170
ephemeralExpiration: attrs.ephemeral ? +attrs.ephemeral : undefined,
171
ephemeralSettingTimestamp: attrs.eph_setting_ts ? +attrs.eph_setting_ts : undefined,
172
readOnly: attrs.read_only === 'true' ? true : undefined,
173
};
174
});
175
logger.info(`got ${chats.length} chats, extracted ${contacts.length} contacts with name`);
176
ev.emit('chats.set', { chats, isLatest: true });
177
}
178
});
179
// got all contacts from phone
180
socketEvents.on('CB:response,type:contacts', async ({ content: data }) => {
181
if (Array.isArray(data)) {
182
const contacts = data.map(({ attrs }) => {
183
return {
184
id: WABinary_1.jidNormalizedUser(attrs.jid),
185
name: attrs.name,
186
notify: attrs.notify,
187
verifiedName: attrs.verify === '2' ? attrs.vname : undefined
188
};
189
});
190
logger.info(`got ${contacts.length} contacts`);
191
ev.emit('contacts.set', { contacts });
192
}
193
});
194
// status updates
195
socketEvents.on('CB:Status,status', json => {
196
const id = WABinary_1.jidNormalizedUser(json[1].id);
197
ev.emit('contacts.update', [{ id, status: json[1].status }]);
198
});
199
// User Profile Name Updates
200
socketEvents.on('CB:Conn,pushname', json => {
201
const { legacy: { user }, connection } = state;
202
if (connection === 'open' && json[1].pushname !== user.name) {
203
user.name = json[1].pushname;
204
ev.emit('connection.update', { legacy: { ...state.legacy, user } });
205
}
206
});
207
// read updates
208
socketEvents.on('CB:action,,read', async ({ content }) => {
209
if (Array.isArray(content)) {
210
const { attrs } = content[0];
211
const update = {
212
id: WABinary_1.jidNormalizedUser(attrs.jid)
213
};
214
if (attrs.type === 'false') {
215
update.unreadCount = -1;
216
}
217
else {
218
update.unreadCount = 0;
219
}
220
ev.emit('chats.update', [update]);
221
}
222
});
223
socketEvents.on('CB:Cmd,type:picture', async (json) => {
224
json = json[1];
225
const id = WABinary_1.jidNormalizedUser(json.jid);
226
const imgUrl = await profilePictureUrl(id).catch(() => '');
227
ev.emit('contacts.update', [{ id, imgUrl }]);
228
});
229
// chat archive, pin etc.
230
socketEvents.on('CB:action,,chat', ({ content }) => {
231
if (Array.isArray(content)) {
232
const [node] = content;
233
executeChatModification(node);
234
}
235
});
236
socketEvents.on('CB:action,,user', (json) => {
237
if (Array.isArray(json.content)) {
238
const user = json.content[0].attrs;
239
if (user.id) {
240
user.id = WABinary_1.jidNormalizedUser(user.id);
241
//ev.emit('contacts.upsert', [user])
242
}
243
else {
244
logger.warn({ json }, 'recv unknown action');
245
}
246
}
247
});
248
// presence updates
249
socketEvents.on('CB:Presence', json => {
250
const update = applyingPresenceUpdate(json[1]);
251
ev.emit('presence.update', update);
252
});
253
// blocklist updates
254
socketEvents.on('CB:Blocklist', json => {
255
json = json[1];
256
const blocklist = json.blocklist;
257
ev.emit('blocklist.set', { blocklist });
258
});
259
socketEvents.on('ws-close', () => {
260
chatsDebounceTimeout.cancel();
261
});
262
return {
263
...sock,
264
sendChatsQuery,
265
profilePictureUrl,
266
chatRead,
267
/**
268
* Modify a given chat (archive, pin etc.)
269
* @param jid the ID of the person/group you are modifiying
270
*/
271
chatModify: async (modification, jid, chatInfo, timestampNow) => {
272
const chatAttrs = { jid: jid };
273
let data = undefined;
274
timestampNow = timestampNow || generics_1.unixTimestampSeconds();
275
if ('archive' in modification) {
276
chatAttrs.type = modification.archive ? 'archive' : 'unarchive';
277
}
278
else if ('pin' in modification) {
279
chatAttrs.type = 'pin';
280
if (modification.pin) {
281
chatAttrs.pin = timestampNow.toString();
282
}
283
else {
284
chatAttrs.previous = chatInfo.pin.toString();
285
}
286
}
287
else if ('mute' in modification) {
288
chatAttrs.type = 'mute';
289
if (modification.mute) {
290
chatAttrs.mute = (timestampNow + modification.mute).toString();
291
}
292
else {
293
chatAttrs.previous = chatInfo.mute.toString();
294
}
295
}
296
else if ('clear' in modification) {
297
chatAttrs.type = 'clear';
298
chatAttrs.modify_tag = Math.round(Math.random() * 1000000).toString();
299
if (modification.clear !== 'all') {
300
data = modification.clear.messages.map(({ id, fromMe }) => ({
301
tag: 'item',
302
attrs: { owner: (!!fromMe).toString(), index: id }
303
}));
304
}
305
}
306
else if ('star' in modification) {
307
chatAttrs.type = modification.star.star ? 'star' : 'unstar';
308
data = modification.star.messages.map(({ id, fromMe }) => ({
309
tag: 'item',
310
attrs: { owner: (!!fromMe).toString(), index: id }
311
}));
312
}
313
else if ('markRead' in modification) {
314
const indexKey = modification.lastMessages[modification.lastMessages.length - 1].key;
315
return chatRead(indexKey, modification.markRead ? 0 : -1);
316
}
317
else if ('delete' in modification) {
318
chatAttrs.type = 'delete';
319
}
320
if ('lastMessages' in modification) {
321
const indexKey = modification.lastMessages[modification.lastMessages.length - 1].key;
322
if (indexKey) {
323
chatAttrs.index = indexKey.id;
324
chatAttrs.owner = indexKey.fromMe ? 'true' : 'false';
325
}
326
}
327
const node = { tag: 'chat', attrs: chatAttrs, content: data };
328
const response = await setQuery([node], [Types_1.WAMetric.chat, Types_1.WAFlag.ignore]);
329
if (config.emitOwnEvents) {
330
// apply it and emit events
331
executeChatModification(node);
332
}
333
return response;
334
},
335
/**
336
* Query whether a given number is registered on WhatsApp
337
* @param str phone number/jid you want to check for
338
* @returns undefined if the number doesn't exists, otherwise the correctly formatted jid
339
*/
340
onWhatsApp: async (str) => {
341
const { status, jid, biz } = await query({
342
json: ['query', 'exist', str],
343
requiresPhoneConnection: false
344
});
345
if (status === 200) {
346
return {
347
exists: true,
348
jid: WABinary_1.jidNormalizedUser(jid),
349
isBusiness: biz
350
};
351
}
352
},
353
/**
354
* Tell someone about your presence -- online, typing, offline etc.
355
* @param jid the ID of the person/group who you are updating
356
* @param type your presence
357
*/
358
sendPresenceUpdate: (type, jid) => (sendNode({
359
binaryTag: [Types_1.WAMetric.presence, Types_1.WAFlag[type]],
360
json: {
361
tag: 'action',
362
attrs: { epoch: currentEpoch().toString(), type: 'set' },
363
content: [
364
{
365
tag: 'presence',
366
attrs: { type: type, to: jid }
367
}
368
]
369
}
370
})),
371
/**
372
* Request updates on the presence of a user
373
* this returns nothing, you'll receive updates in chats.update event
374
* */
375
presenceSubscribe: async (jid) => (sendNode({ json: ['action', 'presence', 'subscribe', jid] })),
376
/** Query the status of the person (see groupMetadata() for groups) */
377
getStatus: async (jid) => {
378
const status = await query({ json: ['query', 'Status', jid], requiresPhoneConnection: false });
379
return status;
380
},
381
setStatus: async (status) => {
382
const response = await setQuery([
383
{
384
tag: 'status',
385
attrs: {},
386
content: Buffer.from(status, 'utf-8')
387
}
388
]);
389
ev.emit('contacts.update', [{ id: state.legacy.user.id, status }]);
390
return response;
391
},
392
/** Updates business profile. */
393
updateBusinessProfile: async (profile) => {
394
var _a;
395
if ((_a = profile.business_hours) === null || _a === void 0 ? void 0 : _a.config) {
396
profile.business_hours.business_config = profile.business_hours.config;
397
delete profile.business_hours.config;
398
}
399
const json = ['action', 'editBusinessProfile', { ...profile, v: 2 }];
400
await query({ json, expect200: true, requiresPhoneConnection: true });
401
},
402
updateProfileName: async (name) => {
403
const response = (await setQuery([
404
{
405
tag: 'profile',
406
attrs: { name }
407
}
408
]));
409
if (config.emitOwnEvents) {
410
const user = { ...state.legacy.user, name };
411
ev.emit('connection.update', { legacy: {
412
...state.legacy, user
413
} });
414
ev.emit('contacts.update', [{ id: user.id, name }]);
415
}
416
return response;
417
},
418
/**
419
* Update the profile picture
420
* @param jid
421
* @param img
422
*/
423
async updateProfilePicture(jid, img) {
424
var _a;
425
jid = WABinary_1.jidNormalizedUser(jid);
426
const data = { img: Buffer.from([]), preview: Buffer.from([]) }; //await generateProfilePicture(img) TODO
427
const tag = this.generateMessageTag();
428
const query = {
429
tag: 'picture',
430
attrs: { jid: jid, id: tag, type: 'set' },
431
content: [
432
{ tag: 'image', attrs: {}, content: data.img },
433
{ tag: 'preview', attrs: {}, content: data.preview }
434
]
435
};
436
const user = (_a = state.legacy) === null || _a === void 0 ? void 0 : _a.user;
437
const { eurl } = await this.setQuery([query], [Types_1.WAMetric.picture, 136], tag);
438
if (config.emitOwnEvents) {
439
if (jid === user.id) {
440
user.imgUrl = eurl;
441
ev.emit('connection.update', {
442
legacy: {
443
...state.legacy,
444
user
445
}
446
});
447
}
448
ev.emit('contacts.update', [{ id: jid, imgUrl: eurl }]);
449
}
450
},
451
/**
452
* Add or remove user from blocklist
453
* @param jid the ID of the person who you are blocking/unblocking
454
* @param type type of operation
455
*/
456
blockUser: async (jid, type = 'add') => {
457
const json = {
458
tag: 'block',
459
attrs: { type },
460
content: [{ tag: 'user', attrs: { jid } }]
461
};
462
await setQuery([json], [Types_1.WAMetric.block, Types_1.WAFlag.ignore]);
463
if (config.emitOwnEvents) {
464
ev.emit('blocklist.update', { blocklist: [jid], type });
465
}
466
},
467
/**
468
* Query Business Profile (Useful for VCards)
469
* @param jid Business Jid
470
* @returns profile object or undefined if not business account
471
*/
472
getBusinessProfile: async (jid) => {
473
jid = WABinary_1.jidNormalizedUser(jid);
474
const { profiles: [{ profile, wid }] } = await query({
475
json: [
476
'query', 'businessProfile',
477
[{ 'wid': jid.replace('@s.whatsapp.net', '@c.us') }],
478
84
479
],
480
expect200: true,
481
requiresPhoneConnection: false,
482
});
483
return {
484
...profile,
485
wid: WABinary_1.jidNormalizedUser(wid)
486
};
487
}
488
};
489
};
490
exports.default = makeChatsSocket;
491
492