alicezetion 1.6.5 → 1.6.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +1 @@
1
- {"nonce":6842598481667284417,"last_updated":{"seconds":1693628493,"nanos":552993000}}
1
+ {"nonce":6820101728818954228,"last_updated":{"seconds":1693628792,"nanos":905350000}}
@@ -0,0 +1,553 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+
6
+ var msgsRecv = 0;
7
+ var identity = function() {};
8
+
9
+ module.exports = function(defaultFuncs, api, ctx) {
10
+ var currentlyRunning = null;
11
+ var globalCallback = identity;
12
+
13
+ var stopListening = function() {
14
+ globalCallback = identity;
15
+ if (currentlyRunning) {
16
+ clearTimeout(currentlyRunning);
17
+ currentlyRunning = null;
18
+ }
19
+ };
20
+
21
+ var prev = Date.now();
22
+ var tmpPrev = Date.now();
23
+ var lastSync = Date.now();
24
+
25
+ var form = {
26
+ channel: "p_" + ctx.userID,
27
+ seq: "0",
28
+ partition: "-2",
29
+ clientid: ctx.clientID,
30
+ viewer_uid: ctx.userID,
31
+ uid: ctx.userID,
32
+ state: "active",
33
+ idle: 0,
34
+ cap: "8",
35
+ msgs_recv: msgsRecv,
36
+ qp: "y",
37
+ pws: "fresh"
38
+ };
39
+
40
+ if (ctx.globalOptions.pageID) {
41
+ form.aiq = ctx.globalOptions.pageID + ",0";
42
+ }
43
+
44
+ /**
45
+ * Get an object maybe representing an event. Handles events it wants to handle
46
+ * and returns true if it did handle an event (and called the globalCallback).
47
+ * Returns false otherwise.
48
+ */
49
+ function handleMessagingEvents(event) {
50
+ switch (event.event) {
51
+ // "read_receipt" event triggers when other people read the user's messages.
52
+ case "read_receipt":
53
+ var fmtMsg;
54
+ try {
55
+ fmtMsg = utils.formatReadReceipt(event);
56
+ } catch (err) {
57
+ globalCallback({
58
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
59
+ detail: err,
60
+ res: event,
61
+ type: "parse_error"
62
+ });
63
+ return true;
64
+ }
65
+ globalCallback(null, fmtMsg);
66
+ return true;
67
+ // "read event" triggers when the user read other people's messages.
68
+ case "read":
69
+ var fmtMsg;
70
+ try {
71
+ fmtMsg = utils.formatRead(event);
72
+ } catch (err) {
73
+ globalCallback({
74
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
75
+ detail: err,
76
+ res: event,
77
+ type: "parse_error"
78
+ });
79
+ return true;
80
+ }
81
+ globalCallback(null, fmtMsg);
82
+ return true;
83
+ default:
84
+ return false;
85
+ }
86
+ }
87
+
88
+ var serverNumber = "0";
89
+
90
+ function listen(servern) {
91
+ if (currentlyRunning == null || !ctx.loggedIn) {
92
+ return;
93
+ }
94
+
95
+ form.idle = ~~(Date.now() / 1000) - prev;
96
+ prev = ~~(Date.now() / 1000);
97
+ var presence = utils.generatePresence(ctx.userID);
98
+ ctx.jar.setCookie(
99
+ "presence=" + presence + "; path=/; domain=.facebook.com; secure",
100
+ "https://www.facebook.com"
101
+ );
102
+ defaultFuncs
103
+ .get(
104
+ "https://" + serverNumber + "-edge-chat.facebook.com/pull",
105
+ ctx.jar,
106
+ form
107
+ )
108
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
109
+ .then(function(resData) {
110
+ var now = Date.now();
111
+ log.info("listen", "Got answer in " + (now - tmpPrev));
112
+ tmpPrev = now;
113
+ if (resData && resData.t === "lb") {
114
+ form.sticky_token = resData.lb_info.sticky;
115
+ form.sticky_pool = resData.lb_info.pool;
116
+ }
117
+
118
+ if (resData && resData.t === "fullReload") {
119
+ form.seq = resData.seq;
120
+ delete form.sticky_pool;
121
+ delete form.sticky_token;
122
+ var form4 = {
123
+ lastSync: ~~(lastSync / 1000)
124
+ };
125
+ defaultFuncs
126
+ .get("https://www.facebook.com/notifications/sync/", ctx.jar, form4)
127
+ .then(utils.saveCookies(ctx.jar))
128
+ .then(function() {
129
+ lastSync = Date.now();
130
+ var form = {
131
+ client: "mercury",
132
+ "folders[0]": "inbox",
133
+ last_action_timestamp: ~~(Date.now() - 60)
134
+ };
135
+ defaultFuncs
136
+ .post(
137
+ "https://www.facebook.com/ajax/mercury/thread_sync.php",
138
+ ctx.jar,
139
+ form
140
+ )
141
+ .then(function() {
142
+ currentlyRunning = setTimeout(listen, 1000);
143
+ });
144
+ });
145
+ return;
146
+ }
147
+
148
+ if (resData.ms) {
149
+ msgsRecv += resData.ms.length;
150
+ var atLeastOne = false;
151
+ resData.ms
152
+ .sort(function(a, b) {
153
+ return a.timestamp - b.timestamp;
154
+ })
155
+ .forEach(function parsePackets(v) {
156
+ switch (v.type) {
157
+ // TODO: 'ttyp' was used before. It changed to 'typ'. We're keeping
158
+ // both for now but we should remove 'ttyp' at some point.
159
+ case "ttyp":
160
+ case "typ":
161
+ if (
162
+ !ctx.globalOptions.listenEvents ||
163
+ (!ctx.globalOptions.selfListen &&
164
+ v.from.toString() === ctx.userID)
165
+ ) {
166
+ return;
167
+ }
168
+ var fmtMsg;
169
+ try {
170
+ fmtMsg = utils.formatTyp(v);
171
+ } catch (err) {
172
+ return globalCallback({
173
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
174
+ detail: err,
175
+ res: v,
176
+ type: "parse_error"
177
+ });
178
+ }
179
+ return globalCallback(null, fmtMsg);
180
+ case "chatproxy-presence":
181
+ // TODO: what happens when you're logged in as a page?
182
+ if (!ctx.globalOptions.updatePresence) {
183
+ return;
184
+ }
185
+
186
+ if (ctx.loggedIn) {
187
+ for (var userID in v.buddyList) {
188
+ var formattedPresence;
189
+ try {
190
+ formattedPresence = utils.formatProxyPresence(
191
+ v.buddyList[userID],
192
+ userID
193
+ );
194
+ } catch (err) {
195
+ return globalCallback({
196
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
197
+ detail: err,
198
+ res: v.buddyList[userID],
199
+ type: "parse_error"
200
+ });
201
+ }
202
+
203
+ if (formattedPresence != null) {
204
+ globalCallback(null, formattedPresence);
205
+ }
206
+ }
207
+ return;
208
+ }
209
+
210
+ break;
211
+ case "buddylist_overlay":
212
+ // TODO: what happens when you're logged in as a page?
213
+ if (!ctx.globalOptions.updatePresence) {
214
+ return;
215
+ }
216
+ // There should be only one key inside overlay
217
+ Object.keys(v.overlay).map(function(userID) {
218
+ var formattedPresence;
219
+ try {
220
+ formattedPresence = utils.formatPresence(
221
+ v.overlay[userID],
222
+ userID
223
+ );
224
+ } catch (err) {
225
+ return globalCallback({
226
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
227
+ detail: err,
228
+ res: v.overlay[userID],
229
+ type: "parse_error"
230
+ });
231
+ }
232
+ if (ctx.loggedIn) {
233
+ return globalCallback(null, formattedPresence);
234
+ }
235
+ });
236
+ break;
237
+ case "delta":
238
+ if (v.delta.class == "NewMessage") {
239
+ if (ctx.globalOptions.pageID &&
240
+ ctx.globalOptions.pageID != v.queue
241
+ )
242
+ return;
243
+
244
+ (function resolveAttachmentUrl(i) {
245
+ if (i == v.delta.attachments.length) {
246
+ var fmtMsg;
247
+ try {
248
+ fmtMsg = utils.formatDeltaMessage(v);
249
+ } catch (err) {
250
+ return globalCallback({
251
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
252
+ detail: err,
253
+ res: v,
254
+ type: "parse_error"
255
+ });
256
+ }
257
+ return !ctx.globalOptions.selfListen &&
258
+ fmtMsg.senderID === ctx.userID ?
259
+ undefined :
260
+ globalCallback(null, fmtMsg);
261
+ } else {
262
+ if (
263
+ v.delta.attachments[i].mercury.attach_type == "photo"
264
+ ) {
265
+ api.resolvePhotoUrl(
266
+ v.delta.attachments[i].fbid,
267
+ (err, url) => {
268
+ if (!err)
269
+ v.delta.attachments[
270
+ i
271
+ ].mercury.metadata.url = url;
272
+ return resolveAttachmentUrl(i + 1);
273
+ }
274
+ );
275
+ } else {
276
+ return resolveAttachmentUrl(i + 1);
277
+ }
278
+ }
279
+ })(0);
280
+ break;
281
+ }
282
+
283
+ if (v.delta.class == "ClientPayload") {
284
+ var clientPayload = utils.decodeClientPayload(
285
+ v.delta.payload
286
+ );
287
+ if (clientPayload && clientPayload.deltas) {
288
+ for (var i in clientPayload.deltas) {
289
+ var delta = clientPayload.deltas[i];
290
+ if (delta.deltaMessageReaction && !!ctx.globalOptions.listenEvents) {
291
+ globalCallback(null, {
292
+ type: "message_reaction",
293
+ threadID: delta.deltaMessageReaction.threadKey
294
+ .threadFbId ?
295
+ delta.deltaMessageReaction.threadKey.threadFbId : delta.deltaMessageReaction.threadKey
296
+ .otherUserFbId,
297
+ messageID: delta.deltaMessageReaction.messageId,
298
+ reaction: delta.deltaMessageReaction.reaction,
299
+ senderID: delta.deltaMessageReaction.senderId,
300
+ userID: delta.deltaMessageReaction.userId,
301
+ timestamp: v.ofd_ts
302
+ });
303
+ } else if (delta.deltaRecallMessageData && !!ctx.globalOptions.listenEvents) {
304
+ globalCallback(null, {
305
+ type: "message_unsend",
306
+ threadID: delta.deltaRecallMessageData.threadKey.threadFbId ?
307
+ delta.deltaRecallMessageData.threadKey.threadFbId : delta.deltaRecallMessageData.threadKey
308
+ .otherUserFbId,
309
+ messageID: delta.deltaRecallMessageData.messageID,
310
+ senderID: delta.deltaRecallMessageData.senderID,
311
+ deletionTimestamp: delta.deltaRecallMessageData.deletionTimestamp,
312
+ timestamp: v.ofd_ts
313
+ });
314
+ } else if (delta.deltaMessageReply) {
315
+ //Mention block - #1
316
+ var mdata =
317
+ delta.deltaMessageReply.message.data === undefined ? [] :
318
+ delta.deltaMessageReply.message.data.prng === undefined ? [] :
319
+ JSON.parse(delta.deltaMessageReply.message.data.prng);
320
+ var m_id = mdata.map(u => u.i);
321
+ var m_offset = mdata.map(u => u.o);
322
+ var m_length = mdata.map(u => u.l);
323
+
324
+ var mentions = {};
325
+
326
+ for (var i = 0; i < m_id.length; i++) {
327
+ mentions[m_id[i]] = delta.deltaMessageReply.message.body.substring(
328
+ m_offset[i],
329
+ m_offset[i] + m_length[i]
330
+ );
331
+ }
332
+ //Mention block - 1#
333
+ //Mention block - #2
334
+ var mdata =
335
+ delta.deltaMessageReply.repliedToMessage.data === undefined ? [] :
336
+ delta.deltaMessageReply.repliedToMessage.data.prng === undefined ? [] :
337
+ JSON.parse(delta.deltaMessageReply.repliedToMessage.data.prng);
338
+ var m_id = mdata.map(u => u.i);
339
+ var m_offset = mdata.map(u => u.o);
340
+ var m_length = mdata.map(u => u.l);
341
+
342
+ var rmentions = {};
343
+
344
+ for (var i = 0; i < m_id.length; i++) {
345
+ rmentions[m_id[i]] = delta.deltaMessageReply.repliedToMessage.body.substring(
346
+ m_offset[i],
347
+ m_offset[i] + m_length[i]
348
+ );
349
+ }
350
+ //Mention block - 2#
351
+
352
+ globalCallback(null, {
353
+ type: "message_reply",
354
+ threadID: delta.deltaMessageReply.message.messageMetadata.threadKey.threadFbId ?
355
+ delta.deltaMessageReply.message.messageMetadata.threadKey.threadFbId : delta.deltaMessageReply.message.messageMetadata.threadKey
356
+ .otherUserFbId,
357
+ messageID: delta.deltaMessageReply.message.messageMetadata.messageId,
358
+ senderID: delta.deltaMessageReply.message.messageMetadata.actorFbId,
359
+ attachments: delta.deltaMessageReply.message.attachments.map(function(att) {
360
+ var mercury = JSON.parse(att.mercuryJSON);
361
+ Object.assign(att, mercury);
362
+ return att;
363
+ }).map(att => utils._formatAttachment(att)),
364
+ body: delta.deltaMessageReply.message.body || "",
365
+ isGroup: !!delta.deltaMessageReply.message.messageMetadata.threadKey.threadFbId,
366
+ mentions: mentions,
367
+ timestamp: v.ofd_ts,
368
+ messageReply: {
369
+ threadID: delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey.threadFbId ?
370
+ delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey.threadFbId : delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey
371
+ .otherUserFbId,
372
+ messageID: delta.deltaMessageReply.repliedToMessage.messageMetadata.messageId,
373
+ senderID: delta.deltaMessageReply.repliedToMessage.messageMetadata.actorFbId,
374
+ attachments: delta.deltaMessageReply.repliedToMessage.attachments.map(function(att) {
375
+ var mercury = JSON.parse(att.mercuryJSON);
376
+ Object.assign(att, mercury);
377
+ return att;
378
+ }).map(att => utils._formatAttachment(att)),
379
+ body: delta.deltaMessageReply.repliedToMessage.body || "",
380
+ isGroup: !!delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey.threadFbId,
381
+ mentions: rmentions
382
+ }
383
+ });
384
+ }
385
+ }
386
+ return;
387
+ }
388
+ }
389
+
390
+ if (v.delta.class !== "NewMessage" &&
391
+ !ctx.globalOptions.listenEvents
392
+ )
393
+ return;
394
+ switch (v.delta.class) {
395
+ case "ReadReceipt":
396
+ var fmtMsg;
397
+ try {
398
+ fmtMsg = utils.formatDeltaReadReceipt(v.delta);
399
+ } catch (err) {
400
+ return globalCallback({
401
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
402
+ detail: err,
403
+ res: v.delta,
404
+ type: "parse_error"
405
+ });
406
+ }
407
+ return globalCallback(null, fmtMsg);
408
+ case "AdminTextMessage":
409
+ switch (v.delta.type) {
410
+ case "change_thread_theme":
411
+ case "change_thread_nickname":
412
+ case "change_thread_icon":
413
+ break;
414
+ case "group_poll":
415
+ var fmtMsg;
416
+ try {
417
+ fmtMsg = utils.formatDeltaEvent(v.delta);
418
+ } catch (err) {
419
+ return globalCallback({
420
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
421
+ detail: err,
422
+ res: v.delta,
423
+ type: "parse_error"
424
+ });
425
+ }
426
+ return globalCallback(null, fmtMsg);
427
+ break;
428
+ default:
429
+ return;
430
+ }
431
+ case "ThreadName":
432
+ case "ParticipantsAddedToGroupThread":
433
+ case "ParticipantLeftGroupThread":
434
+ var formattedEvent;
435
+ try {
436
+ formattedEvent = utils.formatDeltaEvent(v.delta);
437
+ } catch (err) {
438
+ return globalCallback({
439
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
440
+ detail: err,
441
+ res: v.delta,
442
+ type: "parse_error"
443
+ });
444
+ }
445
+ return (!ctx.globalOptions.selfListen &&
446
+ formattedEvent.author.toString() === ctx.userID) ||
447
+ !ctx.loggedIn ?
448
+ undefined :
449
+ globalCallback(null, formattedEvent);
450
+ }
451
+
452
+ break;
453
+ case "messaging":
454
+ if (handleMessagingEvents(v)) {
455
+ return;
456
+ }
457
+ break;
458
+ case "pages_messaging":
459
+ if (
460
+ !ctx.globalOptions.pageID ||
461
+ v.event !== "deliver" ||
462
+ (!ctx.globalOptions.selfListen &&
463
+ (v.message.sender_fbid.toString() === ctx.userID ||
464
+ v.message.sender_fbid.toString() ===
465
+ ctx.globalOptions.pageID)) ||
466
+ v.realtime_viewer_fbid.toString() !==
467
+ ctx.globalOptions.pageID
468
+ ) {
469
+ return;
470
+ }
471
+
472
+ atLeastOne = true;
473
+ if (ctx.loggedIn) {
474
+ var fmtMsg;
475
+ try {
476
+ fmtMsg = utils.formatMessage(v);
477
+ } catch (err) {
478
+ return globalCallback({
479
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
480
+ detail: err,
481
+ res: v,
482
+ type: "parse_error"
483
+ });
484
+ }
485
+ return globalCallback(null, fmtMsg);
486
+ }
487
+ break;
488
+ }
489
+ });
490
+
491
+ if (atLeastOne) {
492
+ // Send deliveryReceipt notification to the server
493
+ var formDeliveryReceipt = {};
494
+
495
+ resData.ms
496
+ .filter(function(v) {
497
+ return (
498
+ v.message &&
499
+ v.message.mid &&
500
+ v.message.sender_fbid.toString() !== ctx.userID
501
+ );
502
+ })
503
+ .forEach(function(val, i) {
504
+ formDeliveryReceipt["[" + i + "]"] = val.message.mid;
505
+ });
506
+
507
+ // If there's at least one, we do the post request
508
+ if (formDeliveryReceipt["[0]"]) {
509
+ defaultFuncs.post(
510
+ "https://www.facebook.com/ajax/mercury/delivery_receipts.php",
511
+ ctx.jar,
512
+ formDeliveryReceipt
513
+ );
514
+ }
515
+ }
516
+ }
517
+
518
+ if (resData.seq) {
519
+ form.seq = resData.seq;
520
+ }
521
+ if (resData.tr) {
522
+ form.traceid = resData.tr;
523
+ }
524
+ if (currentlyRunning) {
525
+ currentlyRunning = setTimeout(listen, Math.random() * 200 + 50);
526
+ }
527
+ return;
528
+ })
529
+ .catch(function(err) {
530
+ if (err.code === "ETIMEDOUT") {
531
+ log.info("listen", "Suppressed timeout error.");
532
+ } else if (err.code === "EAI_AGAIN") {
533
+ serverNumber = (~~(Math.random() * 6)).toString();
534
+ } else {
535
+ log.error("listen", err);
536
+ globalCallback(err);
537
+ }
538
+ if (currentlyRunning) {
539
+ currentlyRunning = setTimeout(listen, Math.random() * 200 + 50);
540
+ }
541
+ });
542
+ }
543
+
544
+ return function(callback) {
545
+ globalCallback = callback;
546
+
547
+ if (!currentlyRunning) {
548
+ currentlyRunning = setTimeout(listen, Math.random() * 200 + 50, callback);
549
+ }
550
+
551
+ return stopListening;
552
+ };
553
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alicezetion",
3
- "version": "1.6.5",
3
+ "version": "1.6.6",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "lint": "./node_modules/.bin/eslint **.js",