alicezetion 1.7.6 → 1.7.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. package/.cache/replit/__replit_disk_meta.json +1 -1
  2. package/.cache/replit/nix/env.json +1 -1
  3. package/.travis.yml +6 -0
  4. package/index.js +118 -654
  5. package/package.json +25 -37
  6. package/replit.nix +4 -3
  7. package/src/addExternalModule.js +5 -13
  8. package/src/addUserToGroup.js +12 -36
  9. package/src/changeAdminStatus.js +37 -85
  10. package/src/changeArchivedStatus.js +9 -15
  11. package/src/changeBio.js +8 -13
  12. package/src/changeBlockedStatus.js +8 -14
  13. package/src/changeGroupImage.js +13 -28
  14. package/src/changeNickname.js +11 -22
  15. package/src/changeThreadColor.js +10 -16
  16. package/src/changeThreadEmoji.js +9 -18
  17. package/src/chat.js +280 -401
  18. package/src/createNewGroup.js +10 -18
  19. package/src/createPoll.js +11 -17
  20. package/src/deleteMessage.js +10 -17
  21. package/src/deleteThread.js +10 -17
  22. package/src/forwardAttachment.js +9 -15
  23. package/src/forwardMessage.js +0 -0
  24. package/src/getCurrentUserID.js +1 -1
  25. package/src/getEmojiUrl.js +2 -3
  26. package/src/getFriendsList.js +10 -18
  27. package/src/getThreadHistory.js +59 -156
  28. package/src/getThreadHistoryDeprecated.js +15 -26
  29. package/src/getThreadInfo.js +42 -68
  30. package/src/getThreadInfoDeprecated.js +13 -25
  31. package/src/getThreadList.js +53 -112
  32. package/src/getThreadListDeprecated.js +12 -30
  33. package/src/getThreadPictures.js +13 -25
  34. package/src/getUserID.js +7 -9
  35. package/src/getUserInfo.js +10 -12
  36. package/src/handleFriendRequest.js +35 -36
  37. package/src/handleMessageRequest.js +10 -18
  38. package/src/httpGet.js +13 -20
  39. package/src/httpPost.js +13 -19
  40. package/src/{sendTypingIndicator.js → leiamnash.js} +19 -44
  41. package/src/listen.js +553 -0
  42. package/src/listenMqtt-Test.js +687 -0
  43. package/src/listenMqtt.js +621 -1224
  44. package/src/logout.js +13 -18
  45. package/src/markAsDelivered.js +10 -17
  46. package/src/markAsRead.js +24 -36
  47. package/src/markAsSeen.js +12 -22
  48. package/src/muteThread.js +9 -15
  49. package/src/react.js +9 -20
  50. package/src/removeUserFromGroup.js +11 -38
  51. package/src/resolvePhotoUrl.js +6 -9
  52. package/src/searchForThread.js +8 -14
  53. package/src/seen.js +10 -17
  54. package/src/setPostReaction.js +22 -63
  55. package/src/setTitle.js +12 -22
  56. package/src/threadColors.js +19 -17
  57. package/src/unfriend.js +9 -15
  58. package/src/{unsend.js → unsendMessage.js} +8 -9
  59. package/test/data/shareAttach.js +146 -0
  60. package/test/data/something.mov +0 -0
  61. package/test/data/test.png +0 -0
  62. package/test/data/test.txt +7 -0
  63. package/test/example-config.json +18 -0
  64. package/test/test-page.js +140 -0
  65. package/test/test.js +385 -0
  66. package/utils.js +27 -120
  67. package/Extra/Database/index.js +0 -399
  68. package/Extra/Database/methods.js +0 -286
  69. package/Extra/ExtraAddons.js +0 -213
  70. package/Extra/ExtraGetThread.js +0 -1
  71. package/Extra/ExtraUptimeRobot.js +0 -59
  72. package/Extra/PM2/ecosystem.config.js +0 -23
  73. package/Extra/Src/Last-Run.js +0 -48
  74. package/Language/index.json +0 -151
  75. package/StateCrypt.js +0 -22
  76. package/broadcast.js +0 -42
  77. package/logger.js +0 -21
  78. package/src/changeAvt.js +0 -91
  79. package/src/getAccessToken.js +0 -32
  80. package/src/getMessage.js +0 -84
  81. package/src/getUserInfoV2.js +0 -35
  82. package/src/httpPostFormData.js +0 -46
@@ -29,10 +29,10 @@ function formatAttachmentsGraphQLResponse(attachment) {
29
29
  // @Undocumented
30
30
  attributionApp: attachment.attribution_app
31
31
  ? {
32
- attributionAppID: attachment.attribution_app.id,
33
- name: attachment.attribution_app.name,
34
- logo: attachment.attribution_app.square_logo
35
- }
32
+ attributionAppID: attachment.attribution_app.id,
33
+ name: attachment.attribution_app.name,
34
+ logo: attachment.attribution_app.square_logo
35
+ }
36
36
  : null
37
37
 
38
38
  // @TODO No idea what this is, should we expose it?
@@ -78,10 +78,10 @@ function formatAttachmentsGraphQLResponse(attachment) {
78
78
  // @Undocumented
79
79
  attributionApp: attachment.attribution_app
80
80
  ? {
81
- attributionAppID: attachment.attribution_app.id,
82
- name: attachment.attribution_app.name,
83
- logo: attachment.attribution_app.square_logo
84
- }
81
+ attributionAppID: attachment.attribution_app.id,
82
+ name: attachment.attribution_app.name,
83
+ logo: attachment.attribution_app.square_logo
84
+ }
85
85
  : null
86
86
  };
87
87
  case "MessageVideo":
@@ -144,56 +144,15 @@ function formatExtensibleAttachment(attachment) {
144
144
  url: attachment.story_attachment.url,
145
145
 
146
146
  title: attachment.story_attachment.title_with_entities.text,
147
- description:
148
- attachment.story_attachment.description &&
149
- attachment.story_attachment.description.text,
150
- source:
151
- attachment.story_attachment.source == null
152
- ? null
153
- : attachment.story_attachment.source.text,
154
-
155
- image:
156
- attachment.story_attachment.media == null
157
- ? null
158
- : attachment.story_attachment.media.animated_image == null &&
159
- attachment.story_attachment.media.image == null
160
- ? null
161
- : (
162
- attachment.story_attachment.media.animated_image ||
163
- attachment.story_attachment.media.image
164
- ).uri,
165
- width:
166
- attachment.story_attachment.media == null
167
- ? null
168
- : attachment.story_attachment.media.animated_image == null &&
169
- attachment.story_attachment.media.image == null
170
- ? null
171
- : (
172
- attachment.story_attachment.media.animated_image ||
173
- attachment.story_attachment.media.image
174
- ).width,
175
- height:
176
- attachment.story_attachment.media == null
177
- ? null
178
- : attachment.story_attachment.media.animated_image == null &&
179
- attachment.story_attachment.media.image == null
180
- ? null
181
- : (
182
- attachment.story_attachment.media.animated_image ||
183
- attachment.story_attachment.media.image
184
- ).height,
185
- playable:
186
- attachment.story_attachment.media == null
187
- ? null
188
- : attachment.story_attachment.media.is_playable,
189
- duration:
190
- attachment.story_attachment.media == null
191
- ? null
192
- : attachment.story_attachment.media.playable_duration_in_ms,
193
- playableUrl:
194
- attachment.story_attachment.media == null
195
- ? null
196
- : attachment.story_attachment.media.playable_url,
147
+ description: attachment.story_attachment.description && attachment.story_attachment.description.text,
148
+ source: attachment.story_attachment.source == null ? null : attachment.story_attachment.source.text,
149
+
150
+ image: attachment.story_attachment.media == null ? null : attachment.story_attachment.media.animated_image == null && attachment.story_attachment.media.image == null ? null : (attachment.story_attachment.media.animated_image || attachment.story_attachment.media.image).uri,
151
+ width: attachment.story_attachment.media == null ? null : attachment.story_attachment.media.animated_image == null && attachment.story_attachment.media.image == null ? null : (attachment.story_attachment.media.animated_image || attachment.story_attachment.media.image).width,
152
+ height: attachment.story_attachment.media == null ? null : attachment.story_attachment.media.animated_image == null && attachment.story_attachment.media.image == null ? null : (attachment.story_attachment.media.animated_image || attachment.story_attachment.media.image).height,
153
+ playable: attachment.story_attachment.media == null ? null : attachment.story_attachment.media.is_playable,
154
+ duration: attachment.story_attachment.media == null ? null : attachment.story_attachment.media.playable_duration_in_ms,
155
+ playableUrl: attachment.story_attachment.media == null ? null : attachment.story_attachment.media.playable_url,
197
156
 
198
157
  subattachments: attachment.story_attachment.subattachments,
199
158
 
@@ -210,52 +169,22 @@ function formatExtensibleAttachment(attachment) {
210
169
  // width: "1280"
211
170
  // }
212
171
  //
213
- properties: attachment.story_attachment.properties.reduce(function(
214
- obj,
215
- cur
216
- ) {
172
+ properties: attachment.story_attachment.properties.reduce(function (obj, cur) {
217
173
  obj[cur.key] = cur.value.text;
218
174
  return obj;
219
- },
220
- {}),
175
+ }, {}),
221
176
 
222
177
  // Deprecated fields
223
178
  animatedImageSize: "", // @Legacy
224
179
  facebookUrl: "", // @Legacy
225
180
  styleList: "", // @Legacy
226
181
  target: "", // @Legacy
227
- thumbnailUrl:
228
- attachment.story_attachment.media == null
229
- ? null
230
- : attachment.story_attachment.media.animated_image == null &&
231
- attachment.story_attachment.media.image == null
232
- ? null
233
- : (
234
- attachment.story_attachment.media.animated_image ||
235
- attachment.story_attachment.media.image
236
- ).uri, // @Legacy
237
- thumbnailWidth:
238
- attachment.story_attachment.media == null
239
- ? null
240
- : attachment.story_attachment.media.animated_image == null &&
241
- attachment.story_attachment.media.image == null
242
- ? null
243
- : (
244
- attachment.story_attachment.media.animated_image ||
245
- attachment.story_attachment.media.image
246
- ).width, // @Legacy
247
- thumbnailHeight:
248
- attachment.story_attachment.media == null
249
- ? null
250
- : attachment.story_attachment.media.animated_image == null &&
251
- attachment.story_attachment.media.image == null
252
- ? null
253
- : (
254
- attachment.story_attachment.media.animated_image ||
255
- attachment.story_attachment.media.image
256
- ).height // @Legacy
182
+ thumbnailUrl: attachment.story_attachment.media == null ? null : attachment.story_attachment.media.animated_image == null && attachment.story_attachment.media.image == null ? null : (attachment.story_attachment.media.animated_image || attachment.story_attachment.media.image).uri, // @Legacy
183
+ thumbnailWidth: attachment.story_attachment.media == null ? null : attachment.story_attachment.media.animated_image == null && attachment.story_attachment.media.image == null ? null : (attachment.story_attachment.media.animated_image || attachment.story_attachment.media.image).width, // @Legacy
184
+ thumbnailHeight: attachment.story_attachment.media == null ? null : attachment.story_attachment.media.animated_image == null && attachment.story_attachment.media.image == null ? null : (attachment.story_attachment.media.animated_image || attachment.story_attachment.media.image).height // @Legacy
257
185
  };
258
- } else return { error: "Don't know what to do with extensible_attachment." };
186
+ }
187
+ else return { error: "Don't know what to do with extensible_attachment." };
259
188
  }
260
189
 
261
190
  function formatReactionsGraphQL(reaction) {
@@ -266,7 +195,7 @@ function formatReactionsGraphQL(reaction) {
266
195
  }
267
196
 
268
197
  function formatEventData(event) {
269
- if (event == null) return {};
198
+ if (event == null) return {}
270
199
 
271
200
  switch (event.__typename) {
272
201
  case "ThemeColorExtensibleMessageAdminText":
@@ -280,7 +209,7 @@ function formatEventData(event) {
280
209
  return { threadIcon: event.thread_icon };
281
210
  case "InstantGameUpdateExtensibleMessageAdminText":
282
211
  return {
283
- gameID: event.game == null ? null : event.game.id,
212
+ gameID: (event.game == null ? null : event.game.id),
284
213
  update_type: event.update_type,
285
214
  collapsed_text: event.collapsed_text,
286
215
  expanded_text: event.expanded_text,
@@ -335,19 +264,15 @@ function formatEventData(event) {
335
264
  case "LightweightEventDeleteExtensibleMessageAdminText":
336
265
  return {};
337
266
  default:
338
- return {
339
- error: "Don't know what to with event data type " + event.__typename
340
- };
267
+ return { error: "Don't know what to with event data type " + event.__typename };
341
268
  }
342
269
  }
343
270
 
344
271
  function formatMessagesGraphQLResponse(data) {
345
272
  var messageThread = data.o0.data.message_thread;
346
- var threadID = messageThread.thread_key.thread_fbid
347
- ? messageThread.thread_key.thread_fbid
348
- : messageThread.thread_key.other_user_id;
273
+ var threadID = messageThread.thread_key.thread_fbid ? messageThread.thread_key.thread_fbid : messageThread.thread_key.other_user_id;
349
274
 
350
- var messages = messageThread.messages.nodes.map(function(d) {
275
+ var messages = messageThread.messages.nodes.map(function (d) {
351
276
  switch (d.__typename) {
352
277
  case "UserMessage":
353
278
  // Give priority to stickers. They're seen as normal messages but we've
@@ -383,13 +308,7 @@ function formatMessagesGraphQLResponse(data) {
383
308
 
384
309
  var mentionsObj = {};
385
310
  if (d.message !== null) {
386
- d.message.ranges.forEach(
387
- e =>
388
- (mentionsObj[e.entity.id] = d.message.text.substr(
389
- e.offset,
390
- e.length
391
- ))
392
- );
311
+ d.message.ranges.forEach(e => mentionsObj[e.entity.id] = d.message.text.substr(e.offset, e.length));
393
312
  }
394
313
 
395
314
  return {
@@ -401,7 +320,7 @@ function formatMessagesGraphQLResponse(data) {
401
320
  : d.extensible_attachment
402
321
  ? [formatExtensibleAttachment(d.extensible_attachment)]
403
322
  : [],
404
- body: d.message !== null ? d.message.text : "",
323
+ body: d.message !== null ? d.message.text : '',
405
324
  isGroup: messageThread.thread_type === "GROUP",
406
325
  messageID: d.message_id,
407
326
  senderID: d.message_sender.id,
@@ -412,9 +331,7 @@ function formatMessagesGraphQLResponse(data) {
412
331
  isUnread: d.unread,
413
332
 
414
333
  // New
415
- messageReactions: d.message_reactions
416
- ? d.message_reactions.map(formatReactionsGraphQL)
417
- : null,
334
+ messageReactions: d.message_reactions ? d.message_reactions.map(formatReactionsGraphQL) : null,
418
335
  isSponsored: d.is_sponsored,
419
336
  snippet: d.snippet
420
337
  };
@@ -445,26 +362,21 @@ function formatMessagesGraphQLResponse(data) {
445
362
  timestamp: d.timestamp_precise,
446
363
  eventType: "change_thread_image",
447
364
  snippet: d.snippet,
448
- eventData:
449
- d.image_with_metadata == null
450
- ? {} /* removed image */
451
- : {
452
- /* image added */
453
- threadImage: {
454
- attachmentID: d.image_with_metadata.legacy_attachment_id,
455
- width: d.image_with_metadata.original_dimensions.x,
456
- height: d.image_with_metadata.original_dimensions.y,
457
- url: d.image_with_metadata.preview.uri
458
- }
459
- },
365
+ eventData: d.image_with_metadata == null
366
+ ? {} /* removed image */
367
+ : {
368
+ /* image added */
369
+ threadImage: {
370
+ attachmentID: d.image_with_metadata.legacy_attachment_id,
371
+ width: d.image_with_metadata.original_dimensions.x,
372
+ height: d.image_with_metadata.original_dimensions.y,
373
+ url: d.image_with_metadata.preview.uri
374
+ }
375
+ },
460
376
 
461
377
  // @Legacy
462
378
  logMessageType: "log:thread-icon",
463
- logMessageData: {
464
- thread_icon: d.image_with_metadata
465
- ? d.image_with_metadata.preview.uri
466
- : null
467
- }
379
+ logMessageData: { thread_icon: d.image_with_metadata ? d.image_with_metadata.preview.uri : null }
468
380
  };
469
381
  case "ParticipantLeftMessage":
470
382
  return {
@@ -478,7 +390,7 @@ function formatMessagesGraphQLResponse(data) {
478
390
  snippet: d.snippet,
479
391
  eventData: {
480
392
  // Array of IDs.
481
- participantsRemoved: d.participants_removed.map(function(p) {
393
+ participantsRemoved: d.participants_removed.map(function (p) {
482
394
  return p.id;
483
395
  })
484
396
  },
@@ -486,7 +398,7 @@ function formatMessagesGraphQLResponse(data) {
486
398
  // @Legacy
487
399
  logMessageType: "log:unsubscribe",
488
400
  logMessageData: {
489
- leftParticipantFbId: d.participants_removed.map(function(p) {
401
+ leftParticipantFbId: d.participants_removed.map(function (p) {
490
402
  return p.id;
491
403
  })
492
404
  }
@@ -503,7 +415,7 @@ function formatMessagesGraphQLResponse(data) {
503
415
  snippet: d.snippet,
504
416
  eventData: {
505
417
  // Array of IDs.
506
- participantsAdded: d.participants_added.map(function(p) {
418
+ participantsAdded: d.participants_added.map(function (p) {
507
419
  return p.id;
508
420
  })
509
421
  },
@@ -511,7 +423,7 @@ function formatMessagesGraphQLResponse(data) {
511
423
  // @Legacy
512
424
  logMessageType: "log:subscribe",
513
425
  logMessageData: {
514
- addedParticipants: d.participants_added.map(function(p) {
426
+ addedParticipants: d.participants_added.map(function (p) {
515
427
  return p.id;
516
428
  })
517
429
  }
@@ -569,22 +481,17 @@ function formatMessagesGraphQLResponse(data) {
569
481
  return messages;
570
482
  }
571
483
 
572
- module.exports = function(defaultFuncs, api, ctx) {
573
- return function getThreadHistoryGraphQL(
574
- threadID,
575
- amount,
576
- timestamp,
577
- callback
578
- ) {
579
- var resolveFunc = function() {};
580
- var rejectFunc = function() {};
581
- var returnPromise = new Promise(function(resolve, reject) {
484
+ module.exports = function (defaultFuncs, api, ctx) {
485
+ return function getThreadHistoryGraphQL(threadID, amount, timestamp, callback) {
486
+ var resolveFunc = function () { };
487
+ var rejectFunc = function () { };
488
+ var returnPromise = new Promise(function (resolve, reject) {
582
489
  resolveFunc = resolve;
583
490
  rejectFunc = reject;
584
491
  });
585
492
 
586
493
  if (!callback) {
587
- callback = function(err, data) {
494
+ callback = function (err, data) {
588
495
  if (err) return rejectFunc(err);
589
496
  resolveFunc(data);
590
497
  };
@@ -593,7 +500,7 @@ module.exports = function(defaultFuncs, api, ctx) {
593
500
  // `queries` has to be a string. I couldn't tell from the dev console. This
594
501
  // took me a really long time to figure out. I deserve a cookie for this.
595
502
  var form = {
596
- av: ctx.globalOptions.pageID,
503
+ "av": ctx.globalOptions.pageID,
597
504
  queries: JSON.stringify({
598
505
  o0: {
599
506
  // This doc_id was valid on February 2nd 2017.
@@ -612,20 +519,16 @@ module.exports = function(defaultFuncs, api, ctx) {
612
519
  defaultFuncs
613
520
  .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
614
521
  .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
615
- .then(function(resData) {
522
+ .then(function (resData) {
616
523
  if (resData.error) throw resData;
617
524
  // This returns us an array of things. The last one is the success /
618
525
  // failure one.
619
526
  // @TODO What do we do in this case?
620
- if (resData[resData.length - 1].error_results !== 0)
621
- throw new Error("There was an error_result.");
527
+ if (resData[resData.length - 1].error_results !== 0) throw new Error("There was an error_result.");
622
528
  callback(null, formatMessagesGraphQLResponse(resData[0]));
623
529
  })
624
- .catch(function(err) {
625
- log.error(
626
- "getThreadHistoryGraphQL",
627
- "Lỗi getThreadHistoryGraphQL Có Thể Do Bạn Spam Quá Nhiều, Hãy Thử Lại !"
628
- );
530
+ .catch(function (err) {
531
+ log.error("getThreadHistoryGraphQL", err);
629
532
  return callback(err);
630
533
  });
631
534
 
@@ -3,17 +3,17 @@
3
3
  var utils = require("../utils");
4
4
  var log = require("npmlog");
5
5
 
6
- module.exports = function(defaultFuncs, api, ctx) {
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
7
  return function getThreadHistory(threadID, amount, timestamp, callback) {
8
- var resolveFunc = function() {};
9
- var rejectFunc = function() {};
10
- var returnPromise = new Promise(function(resolve, reject) {
8
+ var resolveFunc = function () { };
9
+ var rejectFunc = function () { };
10
+ var returnPromise = new Promise(function (resolve, reject) {
11
11
  resolveFunc = resolve;
12
12
  rejectFunc = reject;
13
13
  });
14
14
 
15
15
  if (!callback) {
16
- callback = function(err, threadInfo) {
16
+ callback = function (err, threadInfo) {
17
17
  if (err) return rejectFunc(err);
18
18
  resolveFunc(threadInfo);
19
19
  };
@@ -24,41 +24,33 @@ module.exports = function(defaultFuncs, api, ctx) {
24
24
  client: "mercury"
25
25
  };
26
26
 
27
- api.getUserInfo(threadID, function(err, res) {
27
+ api.getUserInfo(threadID, function (err, res) {
28
28
  if (err) return callback(err);
29
29
  var key = Object.keys(res).length > 0 ? "user_ids" : "thread_fbids";
30
30
  form["messages[" + key + "][" + threadID + "][offset]"] = 0;
31
31
  form["messages[" + key + "][" + threadID + "][timestamp]"] = timestamp;
32
32
  form["messages[" + key + "][" + threadID + "][limit]"] = amount;
33
33
 
34
- if (ctx.globalOptions.pageID)
35
- form.request_user_id = ctx.globalOptions.pageID;
34
+ if (ctx.globalOptions.pageID) form.request_user_id = ctx.globalOptions.pageID;
36
35
 
37
36
  defaultFuncs
38
- .post(
39
- "https://www.facebook.com/ajax/mercury/thread_info.php",
40
- ctx.jar,
41
- form
42
- )
37
+ .post("https://www.facebook.com/ajax/mercury/thread_info.php", ctx.jar, form)
43
38
  .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
44
- .then(function(resData) {
39
+ .then(function (resData) {
45
40
  if (resData.error) throw resData;
46
- else if (!resData.payload)
47
- throw { error: "Could not retrieve thread history." };
41
+ else if (!resData.payload) throw { error: "Could not retrieve thread history." };
48
42
 
49
43
  // Asking for message history from a thread with no message history
50
44
  // will return undefined for actions here
51
45
  if (!resData.payload.actions) resData.payload.actions = [];
52
46
 
53
47
  var userIDs = {};
54
- resData.payload.actions.forEach(
55
- v => (userIDs[v.author.split(":").pop()] = "")
56
- );
48
+ resData.payload.actions.forEach(v => userIDs[v.author.split(":").pop()] = "");
57
49
 
58
- api.getUserInfo(Object.keys(userIDs), function(err, data) {
50
+ api.getUserInfo(Object.keys(userIDs), function (err, data) {
59
51
  if (err) return callback(err); //callback({error: "Could not retrieve user information in getThreadHistory."});
60
52
 
61
- resData.payload.actions.forEach(function(v) {
53
+ resData.payload.actions.forEach(function (v) {
62
54
  var sender = data[v.author.split(":").pop()];
63
55
  if (sender) v.sender_name = sender.name;
64
56
  else v.sender_name = "Facebook User";
@@ -66,13 +58,10 @@ module.exports = function(defaultFuncs, api, ctx) {
66
58
  delete v.author;
67
59
  });
68
60
 
69
- callback(
70
- null,
71
- resData.payload.actions.map(utils.formatHistoryMessage)
72
- );
61
+ callback(null, resData.payload.actions.map(utils.formatHistoryMessage));
73
62
  });
74
63
  })
75
- .catch(function(err) {
64
+ .catch(function (err) {
76
65
  log.error("getThreadHistory", err);
77
66
  return callback(err);
78
67
  });