@dongdev/fca-unofficial 0.0.3 → 0.0.5

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.
Files changed (76) hide show
  1. package/.travis.yml +6 -6
  2. package/CHANGELOG.md +1 -1
  3. package/DOCS.md +1738 -1738
  4. package/LICENSE-MIT +21 -21
  5. package/README.md +219 -219
  6. package/index.js +267 -569
  7. package/lib/login.js +0 -0
  8. package/package.json +3 -3
  9. package/src/addExternalModule.js +19 -15
  10. package/src/addUserToGroup.js +113 -77
  11. package/src/changeAdminStatus.js +79 -47
  12. package/src/changeArchivedStatus.js +55 -41
  13. package/src/changeAvatar.js +126 -0
  14. package/src/changeBio.js +66 -54
  15. package/src/changeBlockedStatus.js +40 -29
  16. package/src/changeGroupImage.js +127 -101
  17. package/src/changeNickname.js +50 -36
  18. package/src/changeThreadColor.js +65 -61
  19. package/src/changeThreadEmoji.js +55 -41
  20. package/src/createNewGroup.js +86 -70
  21. package/src/createPoll.js +71 -59
  22. package/src/deleteMessage.js +56 -44
  23. package/src/deleteThread.js +56 -42
  24. package/src/forwardAttachment.js +60 -47
  25. package/src/getCurrentUserID.js +7 -7
  26. package/src/getEmojiUrl.js +29 -27
  27. package/src/getFriendsList.js +83 -73
  28. package/src/getMessage.js +796 -0
  29. package/src/getThreadHistory.js +666 -537
  30. package/src/getThreadInfo.js +232 -171
  31. package/src/getThreadList.js +241 -213
  32. package/src/getThreadPictures.js +79 -59
  33. package/src/getUserID.js +66 -61
  34. package/src/getUserInfo.js +74 -66
  35. package/src/handleFriendRequest.js +61 -46
  36. package/src/handleMessageRequest.js +65 -47
  37. package/src/httpGet.js +52 -44
  38. package/src/httpPost.js +52 -43
  39. package/src/httpPostFormData.js +63 -0
  40. package/src/listenMqtt.js +877 -709
  41. package/src/logout.js +62 -55
  42. package/src/markAsDelivered.js +58 -47
  43. package/src/markAsRead.js +80 -70
  44. package/src/markAsReadAll.js +49 -39
  45. package/src/markAsSeen.js +59 -48
  46. package/src/muteThread.js +52 -45
  47. package/src/postFormData.js +46 -0
  48. package/src/refreshFb_dtsg.js +81 -0
  49. package/src/removeUserFromGroup.js +79 -45
  50. package/src/resolvePhotoUrl.js +45 -36
  51. package/src/searchForThread.js +53 -42
  52. package/src/sendMessage.js +328 -328
  53. package/src/sendMessageMqtt.js +316 -0
  54. package/src/sendTypingIndicator.js +103 -70
  55. package/src/setMessageReaction.js +106 -98
  56. package/src/setPostReaction.js +102 -95
  57. package/src/setTitle.js +86 -70
  58. package/src/threadColors.js +131 -41
  59. package/src/unfriend.js +52 -42
  60. package/src/unsendMessage.js +49 -39
  61. package/src/uploadAttachment.js +95 -0
  62. package/utils.js +1470 -1196
  63. package/.gitattributes +0 -2
  64. package/src/Screenshot.js +0 -83
  65. package/src/changeAvt.js +0 -85
  66. package/src/getThreadHistoryDeprecated.js +0 -71
  67. package/src/getThreadInfoDeprecated.js +0 -56
  68. package/src/getThreadListDeprecated.js +0 -46
  69. package/src/shareContact.js +0 -46
  70. package/test/data/shareAttach.js +0 -146
  71. package/test/data/something.mov +0 -0
  72. package/test/data/test.png +0 -0
  73. package/test/data/test.txt +0 -7
  74. package/test/example-config.json +0 -18
  75. package/test/test-page.js +0 -140
  76. package/test/test.js +0 -385
@@ -1,171 +1,232 @@
1
- "use strict";
2
-
3
- var utils = require("../utils");
4
- var log = require("npmlog");
5
-
6
- function formatEventReminders(reminder) {
7
- return {
8
- reminderID: reminder.id,
9
- eventCreatorID: reminder.lightweight_event_creator.id,
10
- time: reminder.time,
11
- eventType: reminder.lightweight_event_type.toLowerCase(),
12
- locationName: reminder.location_name,
13
- // @TODO verify this
14
- locationCoordinates: reminder.location_coordinates,
15
- locationPage: reminder.location_page,
16
- eventStatus: reminder.lightweight_event_status.toLowerCase(),
17
- note: reminder.note,
18
- repeatMode: reminder.repeat_mode.toLowerCase(),
19
- eventTitle: reminder.event_title,
20
- triggerMessage: reminder.trigger_message,
21
- secondsToNotifyBefore: reminder.seconds_to_notify_before,
22
- allowsRsvp: reminder.allows_rsvp,
23
- relatedEvent: reminder.related_event,
24
- members: reminder.event_reminder_members.edges.map(function (member) {
25
- return {
26
- memberID: member.node.id,
27
- state: member.guest_list_state.toLowerCase()
28
- };
29
- })
30
- };
31
- }
32
-
33
- function formatThreadGraphQLResponse(data) {
34
- var messageThread = data.o0.data.message_thread;
35
- var threadID = messageThread.thread_key.thread_fbid ? messageThread.thread_key.thread_fbid : messageThread.thread_key.other_user_id;
36
-
37
- // Remove me
38
- var lastM = messageThread.last_message;
39
- var snippetID = lastM && lastM.nodes && lastM.nodes[0] && lastM.nodes[0].message_sender && lastM.nodes[0].message_sender.messaging_actor ? lastM.nodes[0].message_sender.messaging_actor.id : null;
40
- var snippetText = lastM && lastM.nodes && lastM.nodes[0] ? lastM.nodes[0].snippet : null;
41
- var lastR = messageThread.last_read_receipt;
42
- var lastReadTimestamp = lastR && lastR.nodes && lastR.nodes[0] && lastR.nodes[0].timestamp_precise ? lastR.nodes[0].timestamp_precise : null;
43
-
44
- return {
45
- threadID: threadID,
46
- threadName: messageThread.name,
47
- participantIDs: messageThread.all_participants.edges.map(d => d.node.messaging_actor.id),
48
- userInfo: messageThread.all_participants.edges.map(d => ({
49
- id: d.node.messaging_actor.id,
50
- name: d.node.messaging_actor.name,
51
- firstName: d.node.messaging_actor.short_name,
52
- vanity: d.node.messaging_actor.username,
53
- thumbSrc: d.node.messaging_actor.big_image_src.uri,
54
- profileUrl: d.node.messaging_actor.big_image_src.uri,
55
- gender: d.node.messaging_actor.gender,
56
- type: d.node.messaging_actor.__typename,
57
- isFriend: d.node.messaging_actor.is_viewer_friend,
58
- isBirthday: !!d.node.messaging_actor.is_birthday //not sure?
59
- })),
60
- unreadCount: messageThread.unread_count,
61
- messageCount: messageThread.messages_count,
62
- timestamp: messageThread.updated_time_precise,
63
- muteUntil: messageThread.mute_until,
64
- isGroup: messageThread.thread_type == "GROUP",
65
- isSubscribed: messageThread.is_viewer_subscribed,
66
- isArchived: messageThread.has_viewer_archived,
67
- folder: messageThread.folder,
68
- cannotReplyReason: messageThread.cannot_reply_reason,
69
- eventReminders: messageThread.event_reminders ? messageThread.event_reminders.nodes.map(formatEventReminders) : null,
70
- emoji: messageThread.customization_info ? messageThread.customization_info.emoji : null,
71
- color: messageThread.customization_info && messageThread.customization_info.outgoing_bubble_color ? messageThread.customization_info.outgoing_bubble_color.slice(2) : null,
72
- nicknames:
73
- messageThread.customization_info &&
74
- messageThread.customization_info.participant_customizations
75
- ? messageThread.customization_info.participant_customizations.reduce(function (res, val) {
76
- if (val.nickname) res[val.participant_id] = val.nickname;
77
- return res;
78
- }, {})
79
- : {},
80
- adminIDs: messageThread.thread_admins,
81
- approvalMode: Boolean(messageThread.approval_mode),
82
- approvalQueue: messageThread.group_approval_queue.nodes.map(a => ({
83
- inviterID: a.inviter.id,
84
- requesterID: a.requester.id,
85
- timestamp: a.request_timestamp,
86
- request_source: a.request_source // @Undocumented
87
- })),
88
-
89
- // @Undocumented
90
- reactionsMuteMode: messageThread.reactions_mute_mode.toLowerCase(),
91
- mentionsMuteMode: messageThread.mentions_mute_mode.toLowerCase(),
92
- isPinProtected: messageThread.is_pin_protected,
93
- relatedPageThread: messageThread.related_page_thread,
94
-
95
- // @Legacy
96
- name: messageThread.name,
97
- snippet: snippetText,
98
- snippetSender: snippetID,
99
- snippetAttachments: [],
100
- serverTimestamp: messageThread.updated_time_precise,
101
- imageSrc: messageThread.image ? messageThread.image.uri : null,
102
- isCanonicalUser: messageThread.is_canonical_neo_user,
103
- isCanonical: messageThread.thread_type != "GROUP",
104
- recipientsLoadable: true,
105
- hasEmailParticipant: false,
106
- readOnly: false,
107
- canReply: messageThread.cannot_reply_reason == null,
108
- lastMessageTimestamp: messageThread.last_message ? messageThread.last_message.timestamp_precise : null,
109
- lastMessageType: "message",
110
- lastReadTimestamp: lastReadTimestamp,
111
- threadType: messageThread.thread_type == "GROUP" ? 2 : 1
112
- };
113
- }
114
-
115
- module.exports = function (defaultFuncs, api, ctx) {
116
- return function getThreadInfoGraphQL(threadID, callback) {
117
- var resolveFunc = function () { };
118
- var rejectFunc = function () { };
119
- var returnPromise = new Promise(function (resolve, reject) {
120
- resolveFunc = resolve;
121
- rejectFunc = reject;
122
- });
123
-
124
- if (utils.getType(callback) != "Function" && utils.getType(callback) != "AsyncFunction") {
125
- callback = function (err, data) {
126
- if (err) return rejectFunc(err);
127
- resolveFunc(data);
128
- };
129
- }
130
-
131
- // `queries` has to be a string. I couldn't tell from the dev console. This
132
- // took me a really long time to figure out. I deserve a cookie for this.
133
- var form = {
134
- queries: JSON.stringify({
135
- o0: {
136
- // This doc_id is valid as of July 20th, 2020
137
- doc_id: "3449967031715030",
138
- query_params: {
139
- id: threadID,
140
- message_limit: 0,
141
- load_messages: false,
142
- load_read_receipts: false,
143
- before: null
144
- }
145
- }
146
- }),
147
- batch_name: "MessengerGraphQLThreadFetcher"
148
- };
149
-
150
- defaultFuncs
151
- .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
152
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
153
- .then(function (resData) {
154
- if (resData.error) throw resData;
155
- // This returns us an array of things. The last one is the success /
156
- // failure one.
157
- // @TODO What do we do in this case?
158
- if (resData[resData.length - 1].error_results !== 0) {
159
- console.log(resData); //Log more info
160
- throw new Error("well darn there was an error_result");
161
- }
162
- callback(null, formatThreadGraphQLResponse(resData[0]));
163
- })
164
- .catch(function (err) {
165
- log.error("getThreadInfoGraphQL", err);
166
- return callback(err);
167
- });
168
-
169
- return returnPromise;
170
- };
171
- };
1
+ "use strict";
2
+
3
+ const utils = require("../utils");
4
+ const log = require("npmlog");
5
+
6
+ function formatEventReminders(reminder) {
7
+ return {
8
+ reminderID: reminder.id,
9
+ eventCreatorID: reminder.lightweight_event_creator.id,
10
+ time: reminder.time,
11
+ eventType: reminder.lightweight_event_type.toLowerCase(),
12
+ locationName: reminder.location_name,
13
+ // @TODO verify this
14
+ locationCoordinates: reminder.location_coordinates,
15
+ locationPage: reminder.location_page,
16
+ eventStatus: reminder.lightweight_event_status.toLowerCase(),
17
+ note: reminder.note,
18
+ repeatMode: reminder.repeat_mode.toLowerCase(),
19
+ eventTitle: reminder.event_title,
20
+ triggerMessage: reminder.trigger_message,
21
+ secondsToNotifyBefore: reminder.seconds_to_notify_before,
22
+ allowsRsvp: reminder.allows_rsvp,
23
+ relatedEvent: reminder.related_event,
24
+ members: reminder.event_reminder_members.edges.map(function (member) {
25
+ return {
26
+ memberID: member.node.id,
27
+ state: member.guest_list_state.toLowerCase()
28
+ };
29
+ })
30
+ };
31
+ }
32
+
33
+ function formatThreadGraphQLResponse(data) {
34
+ if (data.errors)
35
+ return data.errors;
36
+ const messageThread = data.message_thread;
37
+ if (!messageThread)
38
+ return null;
39
+ const threadID = messageThread.thread_key.thread_fbid
40
+ ? messageThread.thread_key.thread_fbid
41
+ : messageThread.thread_key.other_user_id;
42
+
43
+ // Remove me
44
+ const lastM = messageThread.last_message;
45
+ const snippetID =
46
+ lastM &&
47
+ lastM.nodes &&
48
+ lastM.nodes[0] &&
49
+ lastM.nodes[0].message_sender &&
50
+ lastM.nodes[0].message_sender.messaging_actor
51
+ ? lastM.nodes[0].message_sender.messaging_actor.id
52
+ : null;
53
+ const snippetText =
54
+ lastM && lastM.nodes && lastM.nodes[0] ? lastM.nodes[0].snippet : null;
55
+ const lastR = messageThread.last_read_receipt;
56
+ const lastReadTimestamp =
57
+ lastR && lastR.nodes && lastR.nodes[0] && lastR.nodes[0].timestamp_precise
58
+ ? lastR.nodes[0].timestamp_precise
59
+ : null;
60
+
61
+ return {
62
+ threadID: threadID,
63
+ threadName: messageThread.name,
64
+ participantIDs: messageThread.all_participants.edges.map(d => d.node.messaging_actor.id),
65
+ userInfo: messageThread.all_participants.edges.map(d => ({
66
+ id: d.node.messaging_actor.id,
67
+ name: d.node.messaging_actor.name,
68
+ firstName: d.node.messaging_actor.short_name,
69
+ vanity: d.node.messaging_actor.username,
70
+ url: d.node.messaging_actor.url,
71
+ thumbSrc: d.node.messaging_actor.big_image_src.uri,
72
+ profileUrl: d.node.messaging_actor.big_image_src.uri,
73
+ gender: d.node.messaging_actor.gender,
74
+ type: d.node.messaging_actor.__typename,
75
+ isFriend: d.node.messaging_actor.is_viewer_friend,
76
+ isBirthday: !!d.node.messaging_actor.is_birthday //not sure?
77
+ })),
78
+ unreadCount: messageThread.unread_count,
79
+ messageCount: messageThread.messages_count,
80
+ timestamp: messageThread.updated_time_precise,
81
+ muteUntil: messageThread.mute_until,
82
+ isGroup: messageThread.thread_type == "GROUP",
83
+ isSubscribed: messageThread.is_viewer_subscribed,
84
+ isArchived: messageThread.has_viewer_archived,
85
+ folder: messageThread.folder,
86
+ cannotReplyReason: messageThread.cannot_reply_reason,
87
+ eventReminders: messageThread.event_reminders
88
+ ? messageThread.event_reminders.nodes.map(formatEventReminders)
89
+ : null,
90
+ emoji: messageThread.customization_info
91
+ ? messageThread.customization_info.emoji
92
+ : null,
93
+ color:
94
+ messageThread.customization_info &&
95
+ messageThread.customization_info.outgoing_bubble_color
96
+ ? messageThread.customization_info.outgoing_bubble_color.slice(2)
97
+ : null,
98
+ threadTheme: messageThread.thread_theme,
99
+ nicknames:
100
+ messageThread.customization_info &&
101
+ messageThread.customization_info.participant_customizations
102
+ ? messageThread.customization_info.participant_customizations.reduce(
103
+ function (res, val) {
104
+ if (val.nickname) res[val.participant_id] = val.nickname;
105
+ return res;
106
+ },
107
+ {}
108
+ )
109
+ : {},
110
+ adminIDs: messageThread.thread_admins,
111
+ approvalMode: Boolean(messageThread.approval_mode),
112
+ approvalQueue: messageThread.group_approval_queue.nodes.map(a => ({
113
+ inviterID: a.inviter.id,
114
+ requesterID: a.requester.id,
115
+ timestamp: a.request_timestamp,
116
+ request_source: a.request_source // @Undocumented
117
+ })),
118
+
119
+ // @Undocumented
120
+ reactionsMuteMode: messageThread.reactions_mute_mode.toLowerCase(),
121
+ mentionsMuteMode: messageThread.mentions_mute_mode.toLowerCase(),
122
+ isPinProtected: messageThread.is_pin_protected,
123
+ relatedPageThread: messageThread.related_page_thread,
124
+
125
+ // @Legacy
126
+ name: messageThread.name,
127
+ snippet: snippetText,
128
+ snippetSender: snippetID,
129
+ snippetAttachments: [],
130
+ serverTimestamp: messageThread.updated_time_precise,
131
+ imageSrc: messageThread.image ? messageThread.image.uri : null,
132
+ isCanonicalUser: messageThread.is_canonical_neo_user,
133
+ isCanonical: messageThread.thread_type != "GROUP",
134
+ recipientsLoadable: true,
135
+ hasEmailParticipant: false,
136
+ readOnly: false,
137
+ canReply: messageThread.cannot_reply_reason == null,
138
+ lastMessageTimestamp: messageThread.last_message
139
+ ? messageThread.last_message.timestamp_precise
140
+ : null,
141
+ lastMessageType: "message",
142
+ lastReadTimestamp: lastReadTimestamp,
143
+ threadType: messageThread.thread_type == "GROUP" ? 2 : 1,
144
+
145
+ // update in Wed, 13 Jul 2022 19:41:12 +0700
146
+ inviteLink: {
147
+ enable: messageThread.joinable_mode ? messageThread.joinable_mode.mode == 1 : false,
148
+ link: messageThread.joinable_mode ? messageThread.joinable_mode.link : null
149
+ }
150
+ };
151
+ }
152
+
153
+ module.exports = function (defaultFuncs, api, ctx) {
154
+ return function getThreadInfoGraphQL(threadID, callback) {
155
+ let resolveFunc = function () { };
156
+ let rejectFunc = function () { };
157
+ const returnPromise = new Promise(function (resolve, reject) {
158
+ resolveFunc = resolve;
159
+ rejectFunc = reject;
160
+ });
161
+
162
+ if (utils.getType(callback) != "Function" && utils.getType(callback) != "AsyncFunction") {
163
+ callback = function (err, data) {
164
+ if (err) {
165
+ return rejectFunc(err);
166
+ }
167
+ resolveFunc(data);
168
+ };
169
+ }
170
+
171
+ if (utils.getType(threadID) !== "Array") {
172
+ threadID = [threadID];
173
+ }
174
+
175
+ let form = {};
176
+ // `queries` has to be a string. I couldn't tell from the dev console. This
177
+ // took me a really long time to figure out. I deserve a cookie for this.
178
+ threadID.map(function (t, i) {
179
+ form["o" + i] = {
180
+ doc_id: "3449967031715030",
181
+ query_params: {
182
+ id: t,
183
+ message_limit: 0,
184
+ load_messages: false,
185
+ load_read_receipts: false,
186
+ before: null
187
+ }
188
+ };
189
+ });
190
+
191
+ form = {
192
+ queries: JSON.stringify(form),
193
+ batch_name: "MessengerGraphQLThreadFetcher"
194
+ };
195
+
196
+ defaultFuncs
197
+ .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
198
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
199
+ .then(function (resData) {
200
+
201
+ if (resData.error) {
202
+ throw resData;
203
+ }
204
+ // This returns us an array of things. The last one is the success /
205
+ // failure one.
206
+ // @TODO What do we do in this case?
207
+ // if (resData[resData.length - 1].error_results !== 0) {
208
+ // throw resData[0].o0.errors[0];
209
+ // }
210
+ // if (!resData[0].o0.data.message_thread) {
211
+ // throw new Error("can't find this thread");
212
+ // }
213
+ const threadInfos = {};
214
+ for (let i = resData.length - 2; i >= 0; i--) {
215
+ const threadInfo = formatThreadGraphQLResponse(resData[i][Object.keys(resData[i])[0]].data);
216
+ threadInfos[threadInfo?.threadID || threadID[threadID.length - 1 - i]] = threadInfo;
217
+ }
218
+ if (Object.values(threadInfos).length == 1) {
219
+ callback(null, Object.values(threadInfos)[0]);
220
+ }
221
+ else {
222
+ callback(null, threadInfos);
223
+ }
224
+ })
225
+ .catch(function (err) {
226
+ log.error("getThreadInfoGraphQL", err);
227
+ return callback(err);
228
+ });
229
+
230
+ return returnPromise;
231
+ };
232
+ };