@cexy/hoonfca 1.0.0

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 (84) hide show
  1. package/README.md +83 -0
  2. package/index.js +467 -0
  3. package/package.json +12 -0
  4. package/replit.nix +3 -0
  5. package/src/addExternalModule.js +25 -0
  6. package/src/addUserToGroup.js +98 -0
  7. package/src/changeAdminStatus.js +98 -0
  8. package/src/changeArchivedStatus.js +51 -0
  9. package/src/changeAvatar.js +89 -0
  10. package/src/changeBio.js +74 -0
  11. package/src/changeBlockedStatus.js +45 -0
  12. package/src/changeBlockedStatusMqtt.js +65 -0
  13. package/src/changeCover.js +92 -0
  14. package/src/changeGroupImage.js +110 -0
  15. package/src/changeName.js +106 -0
  16. package/src/changeNickname.js +58 -0
  17. package/src/changeThreadColor.js +62 -0
  18. package/src/changeThreadEmoji.js +54 -0
  19. package/src/changeUsername.js +80 -0
  20. package/src/createCommentPost.js +196 -0
  21. package/src/createNewGroup.js +81 -0
  22. package/src/createPoll.js +64 -0
  23. package/src/createPost.js +285 -0
  24. package/src/data/getThreadInfo.json +1 -0
  25. package/src/deleteMessage.js +55 -0
  26. package/src/deleteThread.js +55 -0
  27. package/src/editMessage.js +66 -0
  28. package/src/follow.js +71 -0
  29. package/src/forwardAttachment.js +57 -0
  30. package/src/getAccess.js +130 -0
  31. package/src/getAvatarUser.js +88 -0
  32. package/src/getBotInitialData.js +59 -0
  33. package/src/getCtx.js +5 -0
  34. package/src/getCurrentUserID.js +5 -0
  35. package/src/getEmojiUrl.js +18 -0
  36. package/src/getFriendsList.js +81 -0
  37. package/src/getMessage.js +827 -0
  38. package/src/getOptions.js +5 -0
  39. package/src/getRegion.js +7 -0
  40. package/src/getThreadHistory.js +496 -0
  41. package/src/getThreadHistoryDeprecated.js +95 -0
  42. package/src/getThreadInfo.js +194 -0
  43. package/src/getThreadInfoDeprecated.js +77 -0
  44. package/src/getThreadList.js +219 -0
  45. package/src/getThreadListDeprecated.js +86 -0
  46. package/src/getThreadPictures.js +85 -0
  47. package/src/getUserID.js +67 -0
  48. package/src/getUserInfo.js +89 -0
  49. package/src/handleFriendRequest.js +56 -0
  50. package/src/handleMessageRequest.js +65 -0
  51. package/src/httpGet.js +53 -0
  52. package/src/httpPost.js +53 -0
  53. package/src/httpPostFormData.js +58 -0
  54. package/src/listenMqtt.js +683 -0
  55. package/src/listenNotification.js +96 -0
  56. package/src/logout.js +77 -0
  57. package/src/markAsDelivered.js +53 -0
  58. package/src/markAsRead.js +74 -0
  59. package/src/markAsReadAll.js +46 -0
  60. package/src/markAsSeen.js +57 -0
  61. package/src/muteThread.js +49 -0
  62. package/src/pinMessage.js +60 -0
  63. package/src/refreshFb_dtsg.js +75 -0
  64. package/src/removeUserFromGroup.js +59 -0
  65. package/src/resolvePhotoUrl.js +47 -0
  66. package/src/searchForThread.js +55 -0
  67. package/src/searchStickers.js +59 -0
  68. package/src/sendMessage.js +444 -0
  69. package/src/sendMessageMqtt.js +326 -0
  70. package/src/sendTypingIndicator.js +54 -0
  71. package/src/setMessageReaction.js +126 -0
  72. package/src/setMessageReactionMqtt.js +74 -0
  73. package/src/setPostReaction.js +103 -0
  74. package/src/setProfileGuard.js +66 -0
  75. package/src/setStoryReaction.js +97 -0
  76. package/src/setTitle.js +100 -0
  77. package/src/shareContact.js +101 -0
  78. package/src/shareLink.js +105 -0
  79. package/src/stopListenMqtt.js +47 -0
  80. package/src/threadColors.js +119 -0
  81. package/src/unfriend.js +58 -0
  82. package/src/unsendMessage.js +51 -0
  83. package/src/uploadAttachment.js +98 -0
  84. package/utils.js +919 -0
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+
3
+ const utils = require("../utils");
4
+
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+ return function changeName(input, format, callback) {
7
+ let cb;
8
+ const rt = new Promise((resolve, reject) => {
9
+ cb = (error) => (error ? reject(error) : resolve());
10
+ });
11
+
12
+ // ইনপুট ওভারলোড হ্যান্ডেল করা হচ্ছে
13
+ if (typeof input === "function") {
14
+ callback = input;
15
+ input = null;
16
+ }
17
+
18
+ if (typeof format === "function") {
19
+ callback = format;
20
+ format = "complete";
21
+ }
22
+
23
+ if (typeof callback === "function") {
24
+ cb = callback;
25
+ }
26
+
27
+ // টাইপ ভ্যালিডেশন
28
+ if (utils.getType(input) !== "Object") {
29
+ const error = "name must be an object, not " + utils.getType(input);
30
+ utils.error("changeName", error); // এখানে ওল্ড কোডের log বাগটি ফিক্স করা হয়েছে
31
+ cb(error);
32
+ return rt;
33
+ }
34
+
35
+ const { first_name, middle_name = "", last_name } = input;
36
+
37
+ if (!first_name || !last_name) {
38
+ utils.error("changeName", "name is not be accepted");
39
+ cb("name is not be accepted");
40
+ return rt;
41
+ }
42
+
43
+ // ফরম্যাট অনুযায়ী ফুল নেম জেনারেট করা
44
+ const middlePart = middle_name !== "" ? middle_name + " " : "";
45
+ let full_name = "";
46
+
47
+ if (format === "complete") {
48
+ full_name = `${last_name} ${middlePart}${first_name}`;
49
+ } else if (format === "standard") {
50
+ full_name = `${last_name} ${first_name}`;
51
+ } else if (format === "reversed") {
52
+ full_name = `${first_name} ${middlePart}${last_name}`;
53
+ } else {
54
+ full_name = `${last_name} ${middlePart}${first_name}`;
55
+ }
56
+
57
+ const form = {
58
+ fb_api_caller_class: "RelayModern",
59
+ fb_api_req_friendly_name: "useFXIMUpdateNameMutation",
60
+ variables: JSON.stringify({
61
+ client_mutation_id: utils.getGUID(),
62
+ family_device_id: "device_id_fetch_datr",
63
+ identity_ids: [ctx.userID],
64
+ full_name,
65
+ first_name,
66
+ middle_name,
67
+ last_name,
68
+ interface: "FB_WEB",
69
+ }),
70
+ server_timestamps: true,
71
+ doc_id: "5763510853763960",
72
+ };
73
+
74
+ // অ্যাসিনক্রোনাস রিকোয়েস্ট হ্যান্ডেল করার জন্য IIFE async ফাংশন
75
+ (async () => {
76
+ try {
77
+ const res = await defaultFuncs.post(
78
+ "https://accountscenter.facebook.com/api/graphql/",
79
+ ctx.jar,
80
+ form,
81
+ null,
82
+ null,
83
+ {
84
+ Origin: "https://accountscenter.facebook.com",
85
+ Referer: `https://accountscenter.facebook.com/profiles/${ctx.userID}/name`,
86
+ }
87
+ );
88
+
89
+ const checkedData = utils.parseAndCheckLogin(ctx, defaultFuncs)(res);
90
+
91
+ if (checkedData.errors) {
92
+ throw checkedData;
93
+ } else if (checkedData.data?.fxim_update_identity_name?.error) {
94
+ throw checkedData.data.fxim_update_identity_name.error;
95
+ }
96
+
97
+ return cb();
98
+ } catch (err) {
99
+ utils.error("changeName", err);
100
+ return cb(err);
101
+ }
102
+ })();
103
+
104
+ return rt;
105
+ };
106
+ };
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+
3
+ const utils = require("../utils");
4
+
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+ return function changeNickname(nickname, threadID, participantID, callback) {
7
+ let resolveFunc = () => {};
8
+ let rejectFunc = () => {};
9
+ const returnPromise = new Promise((resolve, reject) => {
10
+ resolveFunc = resolve;
11
+ rejectFunc = reject;
12
+ });
13
+
14
+ if (!callback) {
15
+ callback = function (err) {
16
+ if (err) return rejectFunc(err);
17
+ resolveFunc();
18
+ };
19
+ }
20
+
21
+ const form = {
22
+ nickname, // ES6 property shorthand
23
+ participant_id: participantID,
24
+ thread_or_other_fbid: threadID,
25
+ };
26
+
27
+ defaultFuncs
28
+ .post(
29
+ "https://www.facebook.com/messaging/save_thread_nickname/?source=thread_settings&dpr=1",
30
+ ctx.jar,
31
+ form
32
+ )
33
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
34
+ .then(function (resData) {
35
+ // স্ট্রিক্ট কম্প্যারিসন (===) ব্যবহার করে এরর কোড চেক করা হচ্ছে
36
+ if (resData.error === 1545014) {
37
+ throw { error: "Trying to change nickname of user isn't in thread" };
38
+ }
39
+ if (resData.error === 1357031) {
40
+ throw {
41
+ error:
42
+ "Trying to change user nickname of a thread that doesn't exist. Have at least one message in the thread before trying to change the user nickname.",
43
+ };
44
+ }
45
+ if (resData.error) {
46
+ throw resData;
47
+ }
48
+
49
+ return callback();
50
+ })
51
+ .catch(function (err) {
52
+ utils.error("changeNickname", err);
53
+ return callback(err);
54
+ });
55
+
56
+ return returnPromise;
57
+ };
58
+ };
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ const utils = require("../utils");
4
+
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+ return function changeThreadColor(color, threadID, callback) {
7
+ let resolveFunc = () => {};
8
+ let rejectFunc = () => {};
9
+ const returnPromise = new Promise((resolve, reject) => {
10
+ resolveFunc = resolve;
11
+ rejectFunc = reject;
12
+ });
13
+
14
+ if (!callback) {
15
+ callback = function (err) {
16
+ if (err) return rejectFunc(err);
17
+ resolveFunc();
18
+ };
19
+ }
20
+
21
+ // কালার ভ্যালিডেশন এবং ফরম্যাটিং (Bug Fix)
22
+ let validatedColor = color;
23
+ if (color !== null && color !== undefined) {
24
+ validatedColor = !isNaN(color) ? color.toString().toLowerCase() : color.toLowerCase();
25
+ }
26
+
27
+ const form = {
28
+ dpr: 1,
29
+ queries: JSON.stringify({
30
+ o0: {
31
+ doc_id: "1727493033983591",
32
+ query_params: {
33
+ data: {
34
+ actor_id: ctx.userID,
35
+ client_mutation_id: "0",
36
+ source: "SETTINGS",
37
+ theme_id: validatedColor,
38
+ thread_id: threadID,
39
+ },
40
+ },
41
+ },
42
+ }),
43
+ };
44
+
45
+ defaultFuncs
46
+ .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
47
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
48
+ .then(function (resData) {
49
+ // এরর রেজাল্ট চেক করা হচ্ছে
50
+ if (resData[resData.length - 1]?.error_results > 0) {
51
+ throw new utils.CustomError(resData[0].o0.errors);
52
+ }
53
+ return callback();
54
+ })
55
+ .catch(function (err) {
56
+ utils.error("changeThreadColor", err);
57
+ return callback(err);
58
+ });
59
+
60
+ return returnPromise;
61
+ };
62
+ };
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ const utils = require("../utils");
4
+
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+ return function changeThreadEmoji(emoji, threadID, callback) {
7
+ let resolveFunc = () => {};
8
+ let rejectFunc = () => {};
9
+ const returnPromise = new Promise((resolve, reject) => {
10
+ resolveFunc = resolve;
11
+ rejectFunc = reject;
12
+ });
13
+
14
+ if (!callback) {
15
+ callback = function (err) {
16
+ if (err) return rejectFunc(err);
17
+ resolveFunc();
18
+ };
19
+ }
20
+
21
+ const form = {
22
+ emoji_choice: emoji,
23
+ thread_or_other_fbid: threadID,
24
+ };
25
+
26
+ defaultFuncs
27
+ .post(
28
+ "https://www.facebook.com/messaging/save_thread_emoji/?source=thread_settings&__pc=EXP1%3Amessengerdotcom_pkg",
29
+ ctx.jar,
30
+ form
31
+ )
32
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
33
+ .then(function (resData) {
34
+ // স্ট্রিক্ট কম্প্যারিসন (===) ব্যবহার করা হয়েছে
35
+ if (resData.error === 1357031) {
36
+ throw {
37
+ error:
38
+ "Trying to change emoji of a chat that doesn't exist. Have at least one message in the thread before trying to change the emoji.",
39
+ };
40
+ }
41
+ if (resData.error) {
42
+ throw resData;
43
+ }
44
+
45
+ return callback();
46
+ })
47
+ .catch(function (err) {
48
+ utils.error("changeThreadEmoji", err);
49
+ return callback(err);
50
+ });
51
+
52
+ return returnPromise;
53
+ };
54
+ };
@@ -0,0 +1,80 @@
1
+ 'use strict';
2
+
3
+ var utils = require('../utils');
4
+
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+ return function changeUsername(username, callback) {
7
+ var resolveFunc = function () {};
8
+ var rejectFunc = function () {};
9
+ var returnPromise = new Promise(function (resolve, reject) {
10
+ resolveFunc = resolve;
11
+ rejectFunc = reject;
12
+ });
13
+
14
+ // কলব্যাক ডিফাইন করা না থাকলে প্রমিজ হ্যান্ডলার সেট করা হচ্ছে
15
+ if (typeof callback !== 'function') {
16
+ callback = function (err, data) {
17
+ if (err) {
18
+ return rejectFunc(err);
19
+ }
20
+ resolveFunc(data);
21
+ };
22
+ }
23
+
24
+ // প্রথম প্যারামিটার হিসেবে ভুলবশত ফাংশন পাস করলে তা হ্যান্ডেল করা
25
+ if (typeof username === 'function') {
26
+ var errorMsg = 'username must be a string, and not ' + utils.getType(username);
27
+ utils.error('changeUsername', errorMsg);
28
+ return username({ error: errorMsg });
29
+ }
30
+
31
+ if (typeof username !== 'string') {
32
+ var errorMsg = 'username must be a string, and not ' + utils.getType(username);
33
+ utils.error('changeUsername', errorMsg);
34
+ return callback({ error: errorMsg });
35
+ }
36
+
37
+ var form = {
38
+ fb_api_caller_class: 'RelayModern',
39
+ fb_api_req_friendly_name: 'useFXIMUpdateUsernameMutation',
40
+ variables: JSON.stringify({
41
+ client_mutation_id: utils.getGUID(),
42
+ family_device_id: "device_id_fetch_datr",
43
+ identity_ids: [ctx.userID.toString()],
44
+ username: username,
45
+ interface: "FB_WEB"
46
+ }),
47
+ server_timestamps: true,
48
+ doc_id: "5737739449613305" // doc_id সাধারণত স্ট্রিং হিসেবে নিরাপদ
49
+ };
50
+
51
+ defaultFuncs
52
+ .post('https://accountscenter.facebook.com/api/graphql/', ctx.jar, form, null, null, {
53
+ Origin: 'https://accountscenter.facebook.com',
54
+ Referer: `https://accountscenter.facebook.com/profiles/${ctx.userID}/username/?entrypoint=fb_account_center`
55
+ })
56
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
57
+ .then(function (res) {
58
+ if (!res) {
59
+ throw { error: "changeUsername returned empty response." };
60
+ }
61
+ if (res.errors) {
62
+ throw res;
63
+ }
64
+
65
+ // রেসপন্স ডাটার ভেতরের এরর অবজেক্ট সেফলি চেক করা
66
+ var updateResult = res.data && res.data.fxim_update_identity_username;
67
+ if (updateResult && updateResult.error) {
68
+ throw updateResult.error;
69
+ }
70
+
71
+ return callback(null, res);
72
+ })
73
+ .catch(function (err) {
74
+ utils.error('changeUsername', err);
75
+ return callback(err);
76
+ });
77
+
78
+ return returnPromise;
79
+ };
80
+ };
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+
3
+ const utils = require("../utils.js");
4
+
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+
7
+ // অ্যাটাচমেন্ট আপলোড করার ফাংশন
8
+ function handleUpload(msg, form) {
9
+ if (!msg.attachments || msg.attachments.length === 0) return Promise.resolve();
10
+
11
+ const uploads = msg.attachments.map(item => {
12
+ if (!utils.isReadableStream(item)) {
13
+ return Promise.reject({ error: "image should be a readable stream and not " + utils.getType(item) });
14
+ }
15
+
16
+ return defaultFuncs
17
+ .postFormData("https://www.facebook.com/ajax/ufi/upload/", ctx.jar, {
18
+ profile_id: ctx.userID,
19
+ source: 19,
20
+ target_id: ctx.userID,
21
+ file: item
22
+ })
23
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
24
+ .then(res => {
25
+ if (res.errors || res.error || !res.payload) throw res;
26
+ return { media: { id: res.payload.fbid } };
27
+ });
28
+ });
29
+
30
+ return Promise.all(uploads).then(results => {
31
+ results.forEach(item => form.input.attachments.push(item));
32
+ });
33
+ }
34
+
35
+ function handleURL(msg, form) {
36
+ if (typeof msg.url === "string") {
37
+ form.input.attachments = [{ link: { external: { url: msg.url } } }];
38
+ }
39
+ }
40
+
41
+ function handleMentions(msg, form) {
42
+ if (!msg.mentions) return;
43
+ for (const item of msg.mentions) {
44
+ const { tag, id, fromIndex } = item;
45
+
46
+ if (typeof tag !== "string") throw new Error("Mention tag must be string");
47
+ if (!id) throw new Error("id must be string");
48
+
49
+ const offset = msg.body.indexOf(tag, fromIndex || 0);
50
+ if (offset < 0) throw new Error(`Mention for "${tag}" not found in message string.`);
51
+
52
+ form.input.message.ranges.push({
53
+ entity: { id },
54
+ length: tag.length,
55
+ offset
56
+ });
57
+ }
58
+ }
59
+
60
+ function handleSticker(msg, form) {
61
+ if (msg.sticker) {
62
+ form.input.attachments = [{ media: { id: msg.sticker } }];
63
+ }
64
+ }
65
+
66
+ // গ্রাফকিউএল রিকোয়েস্ট সাবমিট করার ফাংশন
67
+ function createContent(form) {
68
+ return defaultFuncs
69
+ .post("https://www.facebook.com/api/graphql/", ctx.jar, {
70
+ fb_api_caller_class: "RelayModern",
71
+ fb_api_req_friendly_name: "useCometUFICreateCommentMutation",
72
+ variables: JSON.stringify(form),
73
+ server_timestamps: true,
74
+ doc_id: 6993516810709754
75
+ })
76
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
77
+ .then(res => {
78
+ if (res.errors) throw res;
79
+ const node = res.data.comment_create;
80
+ return {
81
+ id: node.feedback_comment_edge.node.id,
82
+ url: node.feedback_comment_edge.node.feedback.url,
83
+ count: node.feedback.total_comment_count
84
+ };
85
+ });
86
+ }
87
+
88
+ return function createCommentPost(msg, postID, callback, replyCommentID) {
89
+ let cb;
90
+ const returnPromise = new Promise((resolve, reject) => {
91
+ cb = (error, info) => (info ? resolve(info) : reject(error));
92
+ });
93
+
94
+ // ইনপুট ভ্যালিডেশন
95
+ if (typeof msg === "function") {
96
+ const error = "Message must be a string or object!!";
97
+ utils.error("createCommentPost", error);
98
+ msg(error);
99
+ return returnPromise;
100
+ }
101
+ if (typeof postID === "function") {
102
+ const error = "postID must be a string!!";
103
+ utils.error("createCommentPost", error);
104
+ postID(error);
105
+ return returnPromise;
106
+ }
107
+ if (typeof callback === "string") {
108
+ replyCommentID = callback;
109
+ callback = null;
110
+ }
111
+ if (typeof callback === "function") {
112
+ cb = callback;
113
+ }
114
+
115
+ const messageType = utils.getType(msg);
116
+
117
+ if (messageType === "String") {
118
+ msg = {
119
+ body: msg,
120
+ attachments: [],
121
+ mentions: [],
122
+ sticker: null,
123
+ url: null
124
+ };
125
+ } else if (messageType === "Object") {
126
+ msg.mentions = msg.mentions ? (Array.isArray(msg.mentions) ? msg.mentions : [msg.mentions]) : [];
127
+ msg.attachments = msg.attachments ? (Array.isArray(msg.attachments) ? msg.attachments : [msg.attachments]) : [];
128
+ if (isNaN(msg.sticker)) msg.sticker = null;
129
+ if (msg.body && typeof msg.body === "object") msg.body = JSON.stringify(msg.body);
130
+ if (!msg.body) msg.body = "";
131
+ } else {
132
+ const error = "Message must be a string or object!!";
133
+ utils.error("createCommentPost", error);
134
+ cb(error);
135
+ return returnPromise;
136
+ }
137
+
138
+ if (typeof postID !== "string") {
139
+ const error = "postID must be a string!!";
140
+ utils.error("createCommentPost", error);
141
+ cb(error);
142
+ return returnPromise;
143
+ }
144
+
145
+ if (typeof replyCommentID !== "string") replyCommentID = null;
146
+
147
+ // ফর্ম অবজেক্ট ডিক্লেয়ারেশন
148
+ const form = {
149
+ feedLocation: "NEWSFEED",
150
+ feedbackSource: 1,
151
+ groupID: null,
152
+ input: {
153
+ client_mutation_id: Math.round(Math.random() * 19).toString(),
154
+ actor_id: ctx.userID,
155
+ attachments: [],
156
+ feedback_id: Buffer.from("feedback:" + postID).toString("base64"),
157
+ formatting_style: null,
158
+ message: {
159
+ ranges: [],
160
+ text: msg.body
161
+ },
162
+ reply_comment_parent_fbid: replyCommentID
163
+ ? (isNaN(replyCommentID) ? replyCommentID : Buffer.from("comment:" + postID + "_" + replyCommentID).toString("base64"))
164
+ : null,
165
+ reply_target_clicked: !!replyCommentID,
166
+ attribution_id_v2: "CometHomeRoot.react,comet.home,via_cold_start," + Date.now() + ",156248,4748854339,,",
167
+ vod_video_timestamp: null,
168
+ feedback_referrer: "/",
169
+ is_tracking_encrypted: true,
170
+ tracking: [],
171
+ feedback_source: "NEWS_FEED",
172
+ idempotence_token: "client:" + utils.getGUID(),
173
+ session_id: utils.getGUID()
174
+ },
175
+ inviteShortLinkKey: null,
176
+ renderLocation: null,
177
+ scale: 1,
178
+ useDefaultActor: false,
179
+ focusCommentID: null
180
+ };
181
+
182
+ // প্রমিজ চেইন এক্সিকিউশন
183
+ handleUpload(msg, form)
184
+ .then(() => handleURL(msg, form))
185
+ .then(() => handleMentions(msg, form))
186
+ .then(() => handleSticker(msg, form))
187
+ .then(() => createContent(form))
188
+ .then(info => cb(null, info))
189
+ .catch(err => {
190
+ utils.error("createCommentPost", err);
191
+ return cb(err); // বাগ ফিক্স করা হয়েছে
192
+ });
193
+
194
+ return returnPromise;
195
+ };
196
+ };
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+
3
+ const utils = require("../utils");
4
+
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+ return function createNewGroup(participantIDs, groupTitle, callback) {
7
+ // groupTitle-এর জায়গায় ফাংশন পাস করলে তা কলব্যাক হিসেবে সেট হচ্ছে
8
+ if (utils.getType(groupTitle) === "Function") {
9
+ callback = groupTitle;
10
+ groupTitle = null;
11
+ }
12
+
13
+ if (utils.getType(participantIDs) !== "Array") {
14
+ throw { error: "createNewGroup: participantIDs should be an array." };
15
+ }
16
+
17
+ if (participantIDs.length < 2) {
18
+ throw {
19
+ error: "createNewGroup: participantIDs should have at least 2 IDs.",
20
+ };
21
+ }
22
+
23
+ let resolveFunc = () => {};
24
+ let rejectFunc = () => {};
25
+ const returnPromise = new Promise((resolve, reject) => {
26
+ resolveFunc = resolve;
27
+ rejectFunc = reject;
28
+ });
29
+
30
+ if (!callback) {
31
+ callback = function (err, threadID) {
32
+ if (err) return rejectFunc(err);
33
+ resolveFunc(threadID);
34
+ };
35
+ }
36
+
37
+ // map() ব্যবহার করে দ্রুত এবং ক্লিন উপায়ে পার্টিসিপেন্ট অবজেক্ট অ্যারে তৈরি
38
+ const pids = participantIDs.map(id => ({ fbid: id }));
39
+ pids.push({ fbid: ctx.userID }); // বটের নিজের আইডি যুক্ত করা হলো
40
+
41
+ const form = {
42
+ fb_api_caller_class: "RelayModern",
43
+ fb_api_req_friendly_name: "MessengerGroupCreateMutation",
44
+ av: ctx.userID,
45
+ doc_id: "577041672419534",
46
+ variables: JSON.stringify({
47
+ input: {
48
+ entry_point: "jewel_new_group",
49
+ actor_id: ctx.userID,
50
+ participants: pids,
51
+ client_mutation_id: Math.round(Math.random() * 1024).toString(),
52
+ thread_settings: {
53
+ name: groupTitle,
54
+ joinable_mode: "PRIVATE",
55
+ thread_image_fbid: null,
56
+ },
57
+ },
58
+ }),
59
+ };
60
+
61
+ defaultFuncs
62
+ .post("https://www.facebook.com/api/graphql/", ctx.jar, form)
63
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
64
+ .then(function (resData) {
65
+ if (resData.errors) {
66
+ throw resData;
67
+ }
68
+ // সফলভাবে গ্রুপ তৈরি হলে নতুন থ্রেড আইডি (Thread ID) রিটার্ন করা হচ্ছে
69
+ return callback(
70
+ null,
71
+ resData.data.messenger_group_thread_create.thread.thread_key.thread_fbid
72
+ );
73
+ })
74
+ .catch(function (err) {
75
+ utils.error("createNewGroup", err);
76
+ return callback(err);
77
+ });
78
+
79
+ return returnPromise;
80
+ };
81
+ };