@lazyneoaz/metachat 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.
- package/LICENSE +3 -0
- package/README.md +199 -0
- package/index.js +2 -0
- package/package.json +86 -0
- package/src/apis/addExternalModule.js +24 -0
- package/src/apis/addUserToGroup.js +108 -0
- package/src/apis/changeAdminStatus.js +148 -0
- package/src/apis/changeArchivedStatus.js +61 -0
- package/src/apis/changeAvatar.js +103 -0
- package/src/apis/changeBio.js +69 -0
- package/src/apis/changeBlockedStatus.js +54 -0
- package/src/apis/changeGroupImage.js +136 -0
- package/src/apis/changeThreadColor.js +116 -0
- package/src/apis/changeThreadEmoji.js +53 -0
- package/src/apis/comment.js +207 -0
- package/src/apis/createAITheme.js +129 -0
- package/src/apis/createNewGroup.js +79 -0
- package/src/apis/createPoll.js +73 -0
- package/src/apis/deleteMessage.js +44 -0
- package/src/apis/deleteThread.js +52 -0
- package/src/apis/editMessage.js +70 -0
- package/src/apis/emoji.js +124 -0
- package/src/apis/enableAutoSaveAppState.js +69 -0
- package/src/apis/fetchThemeData.js +113 -0
- package/src/apis/follow.js +81 -0
- package/src/apis/forwardAttachment.js +195 -0
- package/src/apis/forwardMessage.js +52 -0
- package/src/apis/friend.js +243 -0
- package/src/apis/gcmember.js +122 -0
- package/src/apis/gcname.js +123 -0
- package/src/apis/gcrule.js +119 -0
- package/src/apis/getAccess.js +111 -0
- package/src/apis/getBotInfo.js +88 -0
- package/src/apis/getBotInitialData.js +43 -0
- package/src/apis/getEmojiUrl.js +40 -0
- package/src/apis/getFriendsList.js +79 -0
- package/src/apis/getMessage.js +423 -0
- package/src/apis/getTheme.js +123 -0
- package/src/apis/getThemeInfo.js +116 -0
- package/src/apis/getThemePictures.js +87 -0
- package/src/apis/getThreadColors.js +119 -0
- package/src/apis/getThreadHistory.js +239 -0
- package/src/apis/getThreadInfo.js +271 -0
- package/src/apis/getThreadList.js +236 -0
- package/src/apis/getThreadPictures.js +58 -0
- package/src/apis/getUserID.js +117 -0
- package/src/apis/getUserInfo.js +513 -0
- package/src/apis/getUserInfoV2.js +146 -0
- package/src/apis/handleFriendRequest.js +66 -0
- package/src/apis/handleMessageRequest.js +50 -0
- package/src/apis/httpGet.js +63 -0
- package/src/apis/httpPost.js +89 -0
- package/src/apis/httpPostFormData.js +69 -0
- package/src/apis/listenMqtt.js +1081 -0
- package/src/apis/listenSpeed.js +178 -0
- package/src/apis/logout.js +63 -0
- package/src/apis/markAsDelivered.js +47 -0
- package/src/apis/markAsRead.js +82 -0
- package/src/apis/markAsReadAll.js +40 -0
- package/src/apis/markAsSeen.js +70 -0
- package/src/apis/mqttDeltaValue.js +252 -0
- package/src/apis/muteThread.js +45 -0
- package/src/apis/nickname.js +132 -0
- package/src/apis/notes.js +163 -0
- package/src/apis/pinMessage.js +150 -0
- package/src/apis/produceMetaTheme.js +160 -0
- package/src/apis/realtime.js +182 -0
- package/src/apis/refreshFb_dtsg.js +94 -0
- package/src/apis/removeUserFromGroup.js +117 -0
- package/src/apis/resolvePhotoUrl.js +58 -0
- package/src/apis/scheduler.js +129 -0
- package/src/apis/searchForThread.js +154 -0
- package/src/apis/sendEffect.js +311 -0
- package/src/apis/sendMessage.js +341 -0
- package/src/apis/sendMessageMqtt.js +271 -0
- package/src/apis/sendTypingIndicator.js +74 -0
- package/src/apis/setMessageReaction.js +27 -0
- package/src/apis/setMessageReactionMqtt.js +61 -0
- package/src/apis/setPostReaction.js +118 -0
- package/src/apis/setThreadTheme.js +210 -0
- package/src/apis/setThreadThemeMqtt.js +94 -0
- package/src/apis/setTitle.js +26 -0
- package/src/apis/share.js +106 -0
- package/src/apis/shareContact.js +66 -0
- package/src/apis/stickers.js +257 -0
- package/src/apis/story.js +181 -0
- package/src/apis/theme.js +233 -0
- package/src/apis/unfriend.js +47 -0
- package/src/apis/unsendMessage.js +17 -0
- package/src/apis/uploadAttachment.js +87 -0
- package/src/database/appStateBackup.js +189 -0
- package/src/database/models/index.js +56 -0
- package/src/database/models/thread.js +31 -0
- package/src/database/models/user.js +32 -0
- package/src/database/threadData.js +101 -0
- package/src/database/userData.js +90 -0
- package/src/engine/client.js +92 -0
- package/src/engine/models/buildAPI.js +118 -0
- package/src/engine/models/loginHelper.js +492 -0
- package/src/engine/models/setOptions.js +88 -0
- package/src/types/index.d.ts +498 -0
- package/src/utils/antiSuspension.js +516 -0
- package/src/utils/auth-helpers.js +149 -0
- package/src/utils/autoReLogin.js +239 -0
- package/src/utils/axios.js +368 -0
- package/src/utils/cache.js +54 -0
- package/src/utils/clients.js +279 -0
- package/src/utils/constants.js +525 -0
- package/src/utils/formatters/data/formatAttachment.js +370 -0
- package/src/utils/formatters/data/formatDelta.js +109 -0
- package/src/utils/formatters/index.js +159 -0
- package/src/utils/formatters/value/formatCookie.js +91 -0
- package/src/utils/formatters/value/formatDate.js +36 -0
- package/src/utils/formatters/value/formatID.js +16 -0
- package/src/utils/formatters.js +1369 -0
- package/src/utils/headers.js +235 -0
- package/src/utils/index.js +153 -0
- package/src/utils/monitoring.js +333 -0
- package/src/utils/rateLimiter.js +251 -0
- package/src/utils/tokenRefresh.js +285 -0
- package/src/utils/user-agents.js +238 -0
- package/src/utils/validation.js +157 -0
package/LICENSE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# @lazyneoaz/metachat
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@lazyneoaz/metachat)
|
|
4
|
+
[](https://www.npmjs.com/package/@lazyneoaz/metachat)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://nodejs.org)
|
|
7
|
+
|
|
8
|
+
Advanced Facebook Chat API client for building Messenger bots — real-time messaging, thread management, MQTT, and session stability.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @lazyneoaz/metachat
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
const { login } = require('@lazyneoaz/metachat');
|
|
24
|
+
|
|
25
|
+
login({ appState: require('./appstate.json') }, (err, api) => {
|
|
26
|
+
if (err) return console.error(err);
|
|
27
|
+
|
|
28
|
+
api.listenMqtt((err, event) => {
|
|
29
|
+
if (err) return console.error(err);
|
|
30
|
+
if (event.type === 'message') {
|
|
31
|
+
api.sendMessage('Hello!', event.threadID);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Promise / async style
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
const { login } = require('@lazyneoaz/metachat');
|
|
41
|
+
|
|
42
|
+
(async () => {
|
|
43
|
+
const api = await login({ appState: require('./appstate.json') });
|
|
44
|
+
|
|
45
|
+
api.listenMqtt((err, event) => {
|
|
46
|
+
if (event.type === 'message') {
|
|
47
|
+
api.sendMessage(`Echo: ${event.body}`, event.threadID);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
})();
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Authentication
|
|
56
|
+
|
|
57
|
+
| Method | Description |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `appState` | Array of cookie objects from a browser session. **Recommended.** |
|
|
60
|
+
| `Cookie` | Raw cookie header string |
|
|
61
|
+
| `email` + `password` | Credential login (may trigger checkpoints — not recommended) |
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## API Reference
|
|
66
|
+
|
|
67
|
+
### Messages
|
|
68
|
+
| Method | Description |
|
|
69
|
+
|---|---|
|
|
70
|
+
| `sendMessage(msg, threadID, [cb])` | Send text, attachments, stickers, mentions |
|
|
71
|
+
| `editMessage(text, messageID, [cb])` | Edit a sent message |
|
|
72
|
+
| `unsendMessage(messageID, [cb])` | Retract a message |
|
|
73
|
+
| `deleteMessage(messageIDs, [cb])` | Delete messages locally |
|
|
74
|
+
| `setMessageReaction(reaction, messageID, [cb])` | React to a message |
|
|
75
|
+
| `sendTypingIndicator(threadID, [cb])` | Show/hide typing indicator |
|
|
76
|
+
| `markAsRead(threadID, [cb])` | Mark thread as read |
|
|
77
|
+
| `markAsDelivered(threadID, messageID, [cb])` | Mark as delivered |
|
|
78
|
+
| `markAsSeen([cb])` | Mark all as seen |
|
|
79
|
+
| `markAsReadAll([cb])` | Mark all threads as read |
|
|
80
|
+
| `uploadAttachment(streams, [cb])` | Upload files, get attachment IDs |
|
|
81
|
+
| `forwardAttachment(ids, threadID, [cb])` | Forward attachments to a thread |
|
|
82
|
+
| `forwardMessage(messageID, threadIDs, [cb])` | Forward a message |
|
|
83
|
+
| `shareContact(text, userID, threadID, [cb])` | Share a contact card |
|
|
84
|
+
| `getMessage(messageID, [cb])` | Fetch a message by ID |
|
|
85
|
+
| `resolvePhotoUrl(fbid, [cb])` | Resolve full-resolution photo URL |
|
|
86
|
+
| `getEmojiUrl(char, size, [pixelRatio])` | Get CDN URL for an emoji image |
|
|
87
|
+
| `getThreadColors([query])` | List all Messenger color themes |
|
|
88
|
+
| `changeThreadColor(color, threadID, [cb])` | Change thread color |
|
|
89
|
+
| `changeThreadEmoji(emoji, threadID, [cb])` | Change thread emoji |
|
|
90
|
+
| `sendEffect(type, msg, threadID, [cb])` | Send a message effect (fire, confetti, etc.) |
|
|
91
|
+
| `pinMessage(messageID, threadID, [cb])` | Pin a message |
|
|
92
|
+
| `setPostReaction(postID, type, [cb])` | React to a Facebook post |
|
|
93
|
+
|
|
94
|
+
### Threads
|
|
95
|
+
| Method | Description |
|
|
96
|
+
|---|---|
|
|
97
|
+
| `getThreadInfo(threadID, [cb])` | Get thread details |
|
|
98
|
+
| `getThreadList(limit, cursor, tags, [cb])` | List threads |
|
|
99
|
+
| `getThreadHistory(threadID, amount, timestamp, [cb])` | Get message history |
|
|
100
|
+
| `getThreadPictures(threadID, offset, limit, [cb])` | Get shared photos |
|
|
101
|
+
| `getThemePictures(themeID, [cb])` | Get theme asset images |
|
|
102
|
+
| `searchForThread(query, [cb])` | Search threads |
|
|
103
|
+
| `createNewGroup(name, userIDs, [cb])` | Create a group |
|
|
104
|
+
| `addUserToGroup(userID, threadID, [cb])` | Add user to group |
|
|
105
|
+
| `removeUserFromGroup(userID, threadID, [cb])` | Remove user from group |
|
|
106
|
+
| `changeAdminStatus(threadID, userID, adminStatus, [cb])` | Set admin status |
|
|
107
|
+
| `changeGroupImage(image, threadID, [cb])` | Update group photo |
|
|
108
|
+
| `changeNickname(nickname, threadID, participantID, [cb])` | Set nickname |
|
|
109
|
+
| `setTitle(title, threadID, [cb])` | Change group name |
|
|
110
|
+
| `gcname(name, threadID, [cb])` | Change group name (MQTT) |
|
|
111
|
+
| `createPoll(title, threadID, options, [cb])` | Create a poll |
|
|
112
|
+
| `createAITheme(prompt, threadID, [cb])` | Create AI-generated theme |
|
|
113
|
+
| `deleteThread(threadID, [cb])` | Delete a thread |
|
|
114
|
+
| `changeArchivedStatus(threadID, archived, [cb])` | Archive/unarchive |
|
|
115
|
+
| `muteThread(threadID, muteSeconds, [cb])` | Mute notifications |
|
|
116
|
+
| `handleMessageRequest(threadID, accept, [cb])` | Accept/decline message request |
|
|
117
|
+
| `getTheme(threadID, [cb])` | Get thread theme |
|
|
118
|
+
| `setThreadTheme(threadID, themeID, [cb])` | Set thread theme |
|
|
119
|
+
|
|
120
|
+
### Users
|
|
121
|
+
| Method | Description |
|
|
122
|
+
|---|---|
|
|
123
|
+
| `getUserInfo(userIDs, [cb])` | Get user info by ID(s) |
|
|
124
|
+
| `getUserInfoV2(userID, [cb])` | Alternative user info endpoint |
|
|
125
|
+
| `getUserID(name, [cb])` | Resolve username to user ID |
|
|
126
|
+
| `getFriendsList([cb])` | Get friends list |
|
|
127
|
+
| `getCurrentUserID()` | Get the logged-in user's ID |
|
|
128
|
+
|
|
129
|
+
### Account
|
|
130
|
+
| Method | Description |
|
|
131
|
+
|---|---|
|
|
132
|
+
| `changeAvatar(image, [cb])` | Update profile picture |
|
|
133
|
+
| `changeBio(bio, [cb])` | Update bio |
|
|
134
|
+
| `changeBlockedStatus(userID, block, [cb])` | Block/unblock a user |
|
|
135
|
+
| `handleFriendRequest(userID, accept, [cb])` | Accept/decline friend request |
|
|
136
|
+
| `unfriend(userID, [cb])` | Remove friend |
|
|
137
|
+
| `follow(userID, follow, [cb])` | Follow/unfollow a user |
|
|
138
|
+
| `refreshFb_dtsg([payload], [cb])` | Refresh session security token |
|
|
139
|
+
| `enableAutoSaveAppState([options])` | Auto-save cookies to file |
|
|
140
|
+
| `logout([cb])` | End session |
|
|
141
|
+
| `addExternalModule(name, module)` | Add an external module |
|
|
142
|
+
|
|
143
|
+
### HTTP Utilities
|
|
144
|
+
| Method | Description |
|
|
145
|
+
|---|---|
|
|
146
|
+
| `httpGet(url, qs, [cb])` | Authenticated GET request |
|
|
147
|
+
| `httpPost(url, form, [cb])` | Authenticated POST request |
|
|
148
|
+
| `httpPostFormData(url, form, [cb])` | Multipart POST request |
|
|
149
|
+
|
|
150
|
+
### Realtime
|
|
151
|
+
| Method | Description |
|
|
152
|
+
|---|---|
|
|
153
|
+
| `listenMqtt(cb)` | Start MQTT listener for real-time events |
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Events
|
|
158
|
+
|
|
159
|
+
| Type | Description |
|
|
160
|
+
|---|---|
|
|
161
|
+
| `message` | Incoming message |
|
|
162
|
+
| `message_reply` | Reply to a message |
|
|
163
|
+
| `message_reaction` | Reaction added/removed |
|
|
164
|
+
| `message_unsend` | Message retracted |
|
|
165
|
+
| `event` | Thread event (join, leave, name change, etc.) |
|
|
166
|
+
| `typ` | Typing indicator |
|
|
167
|
+
| `read` / `read_receipt` | Read receipt |
|
|
168
|
+
| `presence` | Online/offline status |
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Options
|
|
173
|
+
|
|
174
|
+
```js
|
|
175
|
+
api.setOptions({
|
|
176
|
+
listenEvents: true, // receive thread events (joins, leaves, etc.)
|
|
177
|
+
selfListen: false, // receive own messages
|
|
178
|
+
autoMarkRead: false, // auto-mark incoming messages as read
|
|
179
|
+
autoReconnect: true, // reconnect MQTT on disconnect
|
|
180
|
+
online: false, // appear online
|
|
181
|
+
logLevel: 'info', // 'silent' | 'info' | 'warn' | 'error'
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Credits
|
|
188
|
+
|
|
189
|
+
Developed and maintained by **NeoKEX**
|
|
190
|
+
|
|
191
|
+
- GitHub: [https://github.com/lazyneoaz](https://github.com/lazyneoaz)
|
|
192
|
+
- Website: [https://neoaz.is-a.dev](https://neoaz.is-a.dev)
|
|
193
|
+
- npm: [https://www.npmjs.com/package/@lazyneoaz/metachat](https://www.npmjs.com/package/@lazyneoaz/metachat)
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## License
|
|
198
|
+
|
|
199
|
+
MIT
|
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lazyneoaz/metachat",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "commonjs",
|
|
5
|
+
"types": "src/types/index.d.ts",
|
|
6
|
+
"description": "Advanced Facebook Chat API client for building Messenger bots — real-time messaging, thread management, MQTT, and session stability.",
|
|
7
|
+
"main": "index.js",
|
|
8
|
+
"files": [
|
|
9
|
+
"index.js",
|
|
10
|
+
"src/",
|
|
11
|
+
"LICENSE",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/lazyneoaz/metachat.git"
|
|
17
|
+
},
|
|
18
|
+
"author": "NeoKEX",
|
|
19
|
+
"contributors": [
|
|
20
|
+
"NeoKEX"
|
|
21
|
+
],
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/lazyneoaz/metachat/issues"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://neoaz.is-a.dev",
|
|
27
|
+
"keywords": [
|
|
28
|
+
"facebook",
|
|
29
|
+
"messenger",
|
|
30
|
+
"chat",
|
|
31
|
+
"bot",
|
|
32
|
+
"fca",
|
|
33
|
+
"mqtt",
|
|
34
|
+
"messaging",
|
|
35
|
+
"api",
|
|
36
|
+
"automation",
|
|
37
|
+
"facebook-chat-api",
|
|
38
|
+
"metachat"
|
|
39
|
+
],
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"axios": "^1.13.5",
|
|
42
|
+
"axios-cookiejar-support": "^4.0.7",
|
|
43
|
+
"bluebird": "^3.7.2",
|
|
44
|
+
"cheerio": "^1.0.0",
|
|
45
|
+
"cli-progress": "^3.12.0",
|
|
46
|
+
"deepdash": "^5.3.9",
|
|
47
|
+
"duplexify": "^4.1.3",
|
|
48
|
+
"form-data": "^4.0.4",
|
|
49
|
+
"gradient-string": "^3.0.0",
|
|
50
|
+
"https-proxy-agent": "^7.0.6",
|
|
51
|
+
"jsonpath-plus": "^10.3.0",
|
|
52
|
+
"lodash": "^4.17.21",
|
|
53
|
+
"mqtt": "^4.3.8",
|
|
54
|
+
"node-cron": "^3.0.3",
|
|
55
|
+
"ora": "^9.4.0",
|
|
56
|
+
"picocolors": "^1.1.1",
|
|
57
|
+
"sequelize": "^6.37.5",
|
|
58
|
+
"sqlite3": "^5.1.7",
|
|
59
|
+
"totp-generator": "^2.0.1",
|
|
60
|
+
"tough-cookie": "^4.1.4",
|
|
61
|
+
"undici": "^6.21.0",
|
|
62
|
+
"uuid": "^9.0.1",
|
|
63
|
+
"ws": "^8.18.0"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@types/form-data": "^2.2.1",
|
|
67
|
+
"@types/node": "^20.17.6",
|
|
68
|
+
"@types/tough-cookie": "^4.0.5",
|
|
69
|
+
"eslint": "^9.15.0",
|
|
70
|
+
"mocha": "^10.7.3",
|
|
71
|
+
"prettier": "^3.4.2",
|
|
72
|
+
"ts-node": "^10.9.2",
|
|
73
|
+
"typescript": "^5.7.2"
|
|
74
|
+
},
|
|
75
|
+
"engines": {
|
|
76
|
+
"node": ">=18.0.0"
|
|
77
|
+
},
|
|
78
|
+
"scripts": {
|
|
79
|
+
"validate": "npm pack --dry-run",
|
|
80
|
+
"prepack": "echo \"Preparing @lazyneoaz/metachat for npm...\"",
|
|
81
|
+
"test": "echo \"No tests configured yet\""
|
|
82
|
+
},
|
|
83
|
+
"publishConfig": {
|
|
84
|
+
"access": "public"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const utils = require('../utils');
|
|
3
|
+
|
|
4
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
5
|
+
return function addExternalModule(moduleObj) {
|
|
6
|
+
if (utils.getType(moduleObj) == "Object") {
|
|
7
|
+
for (const apiName in moduleObj) {
|
|
8
|
+
if (utils.getType(moduleObj[apiName]) == "Function") {
|
|
9
|
+
api[apiName] = moduleObj[apiName](defaultFuncs, api, ctx);
|
|
10
|
+
} else {
|
|
11
|
+
throw new Error(
|
|
12
|
+
`Item "${apiName}" in moduleObj must be a function, not ${utils.getType(
|
|
13
|
+
moduleObj[apiName],
|
|
14
|
+
)}!`,
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
} else {
|
|
19
|
+
throw new Error(
|
|
20
|
+
`moduleObj must be an object, not ${utils.getType(moduleObj)}!`,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const utils = require('../utils');
|
|
4
|
+
|
|
5
|
+
module.exports = (defaultFuncs, api, ctx) => {
|
|
6
|
+
return async function addUserToGroup(userID, 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 = (err, result) => {
|
|
16
|
+
if (err) return rejectFunc(err);
|
|
17
|
+
resolveFunc(result);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
if (!ctx.mqttClient) {
|
|
23
|
+
throw new Error("Not connected to MQTT. Please use listenMqtt first.");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (utils.getType(threadID) !== "Number" && utils.getType(threadID) !== "String") {
|
|
27
|
+
throw new Error("ThreadID should be of type Number or String");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (utils.getType(userID) !== "Array") {
|
|
31
|
+
userID = [userID];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const reqID = ++ctx.wsReqNumber;
|
|
35
|
+
const taskID = ++ctx.wsTaskNumber;
|
|
36
|
+
|
|
37
|
+
const payload = {
|
|
38
|
+
epoch_id: utils.generateOfflineThreadingID(),
|
|
39
|
+
tasks: [
|
|
40
|
+
{
|
|
41
|
+
failure_count: null,
|
|
42
|
+
label: "23",
|
|
43
|
+
payload: JSON.stringify({
|
|
44
|
+
thread_key: threadID,
|
|
45
|
+
contact_ids: userID,
|
|
46
|
+
sync_group: 1
|
|
47
|
+
}),
|
|
48
|
+
queue_name: threadID.toString(),
|
|
49
|
+
task_id: taskID
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
version_id: "24502707779384158"
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const form = JSON.stringify({
|
|
56
|
+
app_id: "772021112871879",
|
|
57
|
+
payload: JSON.stringify(payload),
|
|
58
|
+
request_id: reqID,
|
|
59
|
+
type: 3
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
let responseHandled = false;
|
|
63
|
+
const handleRes = (topic, message) => {
|
|
64
|
+
if (topic !== "/ls_resp" || responseHandled) return;
|
|
65
|
+
let jsonMsg;
|
|
66
|
+
try {
|
|
67
|
+
jsonMsg = JSON.parse(message.toString());
|
|
68
|
+
jsonMsg.payload = JSON.parse(jsonMsg.payload);
|
|
69
|
+
} catch {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (jsonMsg.request_id !== reqID) return;
|
|
73
|
+
responseHandled = true;
|
|
74
|
+
clearTimeout(timeout);
|
|
75
|
+
ctx.mqttClient.removeListener("message", handleRes);
|
|
76
|
+
callback(null, { success: true, response: jsonMsg.payload });
|
|
77
|
+
resolveFunc({ success: true, response: jsonMsg.payload });
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const timeout = setTimeout(() => {
|
|
81
|
+
if (!responseHandled) {
|
|
82
|
+
responseHandled = true;
|
|
83
|
+
ctx.mqttClient.removeListener("message", handleRes);
|
|
84
|
+
const err = new Error("MQTT request timeout");
|
|
85
|
+
callback(err);
|
|
86
|
+
rejectFunc(err);
|
|
87
|
+
}
|
|
88
|
+
}, 30000);
|
|
89
|
+
|
|
90
|
+
ctx.mqttClient.on("message", handleRes);
|
|
91
|
+
ctx.mqttClient.publish("/ls_req", form, { qos: 1, retain: false }, (err) => {
|
|
92
|
+
if (err && !responseHandled) {
|
|
93
|
+
responseHandled = true;
|
|
94
|
+
clearTimeout(timeout);
|
|
95
|
+
ctx.mqttClient.removeListener("message", handleRes);
|
|
96
|
+
callback(err);
|
|
97
|
+
rejectFunc(err);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
} catch (err) {
|
|
101
|
+
utils.error("addUserToGroup", err);
|
|
102
|
+
callback(err);
|
|
103
|
+
rejectFunc(err);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return returnPromise;
|
|
107
|
+
};
|
|
108
|
+
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const utils = require('../utils');
|
|
4
|
+
|
|
5
|
+
function generateOfflineThreadingID() {
|
|
6
|
+
return Date.now().toString() + Math.floor(Math.random() * 1000000).toString();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function getType(obj) {
|
|
10
|
+
return Object.prototype.toString.call(obj).slice(8, -1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
14
|
+
return function changeAdminStatus(threadID, adminID, adminStatus, callback) {
|
|
15
|
+
let resolveFunc = function() {};
|
|
16
|
+
let rejectFunc = function() {};
|
|
17
|
+
const returnPromise = new Promise(function(resolve, reject) {
|
|
18
|
+
resolveFunc = resolve;
|
|
19
|
+
rejectFunc = reject;
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (!callback) {
|
|
23
|
+
callback = function(err, data) {
|
|
24
|
+
if (err) return rejectFunc(err);
|
|
25
|
+
resolveFunc(data);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (getType(threadID) !== "String") {
|
|
30
|
+
return callback({ error: "changeAdminStatus: threadID must be a string" });
|
|
31
|
+
}
|
|
32
|
+
if (getType(adminID) !== "String" && getType(adminID) !== "Array") {
|
|
33
|
+
return callback({ error: "changeAdminStatus: adminID must be a string or an array" });
|
|
34
|
+
}
|
|
35
|
+
if (getType(adminStatus) !== "Boolean") {
|
|
36
|
+
return callback({ error: "changeAdminStatus: adminStatus must be true or false" });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (ctx.mqttClient) {
|
|
40
|
+
const tasks = [];
|
|
41
|
+
const isAdmin = adminStatus ? 1 : 0;
|
|
42
|
+
const epochID = generateOfflineThreadingID();
|
|
43
|
+
|
|
44
|
+
if (getType(adminID) === "Array") {
|
|
45
|
+
adminID.forEach((id, index) => {
|
|
46
|
+
tasks.push({
|
|
47
|
+
failure_count: null,
|
|
48
|
+
label: "25",
|
|
49
|
+
payload: JSON.stringify({
|
|
50
|
+
thread_key: threadID,
|
|
51
|
+
contact_id: id,
|
|
52
|
+
is_admin: isAdmin
|
|
53
|
+
}),
|
|
54
|
+
queue_name: "admin_status",
|
|
55
|
+
task_id: index + 1
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
tasks.push({
|
|
60
|
+
failure_count: null,
|
|
61
|
+
label: "25",
|
|
62
|
+
payload: JSON.stringify({
|
|
63
|
+
thread_key: threadID,
|
|
64
|
+
contact_id: adminID,
|
|
65
|
+
is_admin: isAdmin
|
|
66
|
+
}),
|
|
67
|
+
queue_name: "admin_status",
|
|
68
|
+
task_id: 1
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let count_req = 0;
|
|
73
|
+
const form = JSON.stringify({
|
|
74
|
+
app_id: "2220391788200892",
|
|
75
|
+
payload: JSON.stringify({
|
|
76
|
+
epoch_id: epochID,
|
|
77
|
+
tasks: tasks,
|
|
78
|
+
version_id: "8798795233522156"
|
|
79
|
+
}),
|
|
80
|
+
request_id: ++count_req,
|
|
81
|
+
type: 3
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
ctx.mqttClient.publish("/ls_req", form, {}, (err, _packet) => {
|
|
85
|
+
if (err) {
|
|
86
|
+
utils.error("changeAdminStatus (MQTT)", err);
|
|
87
|
+
return callback(err);
|
|
88
|
+
} else {
|
|
89
|
+
utils.log("Admin status changed successfully via MQTT");
|
|
90
|
+
return callback(null, { success: true });
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
} else {
|
|
94
|
+
utils.warn("MQTT client not available, using HTTP fallback for changeAdminStatus");
|
|
95
|
+
const tasks = [];
|
|
96
|
+
const epochID = generateOfflineThreadingID();
|
|
97
|
+
|
|
98
|
+
if (getType(adminID) === "Array") {
|
|
99
|
+
adminID.forEach((id, index) => {
|
|
100
|
+
tasks.push({
|
|
101
|
+
label: '25',
|
|
102
|
+
payload: JSON.stringify({ thread_key: threadID, contact_id: id, is_admin: adminStatus }),
|
|
103
|
+
queue_name: 'admin_status',
|
|
104
|
+
task_id: index + 1,
|
|
105
|
+
failure_count: null
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
} else {
|
|
109
|
+
tasks.push({
|
|
110
|
+
label: '25',
|
|
111
|
+
payload: JSON.stringify({ thread_key: threadID, contact_id: adminID, is_admin: adminStatus }),
|
|
112
|
+
queue_name: 'admin_status',
|
|
113
|
+
task_id: 1,
|
|
114
|
+
failure_count: null
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const form = {
|
|
119
|
+
fb_dtsg: ctx.fb_dtsg,
|
|
120
|
+
request_id: 1,
|
|
121
|
+
type: 3,
|
|
122
|
+
payload: {
|
|
123
|
+
version_id: '3816854585040595',
|
|
124
|
+
tasks: tasks,
|
|
125
|
+
epoch_id: epochID,
|
|
126
|
+
data_trace_id: null
|
|
127
|
+
},
|
|
128
|
+
app_id: '772021112871879'
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
form.payload = JSON.stringify(form.payload);
|
|
132
|
+
|
|
133
|
+
defaultFuncs
|
|
134
|
+
.post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
|
|
135
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
|
136
|
+
.then(() => {
|
|
137
|
+
utils.log("Admin status changed successfully via HTTP");
|
|
138
|
+
callback(null, { success: true });
|
|
139
|
+
})
|
|
140
|
+
.catch(err => {
|
|
141
|
+
utils.error("changeAdminStatus (HTTP)", err);
|
|
142
|
+
callback(err);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return returnPromise;
|
|
147
|
+
};
|
|
148
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const utils = require('../utils');
|
|
4
|
+
|
|
5
|
+
module.exports = (defaultFuncs, api, ctx) => {
|
|
6
|
+
return async function changeArchivedStatus(threadIDs, archive, 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 = (err, result) => {
|
|
16
|
+
if (err) return rejectFunc(err);
|
|
17
|
+
resolveFunc(result);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
if (utils.getType(archive) === "Function") {
|
|
23
|
+
callback = archive;
|
|
24
|
+
archive = true;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (utils.getType(archive) !== "Boolean") {
|
|
28
|
+
throw new Error("archive parameter must be a boolean");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!Array.isArray(threadIDs)) {
|
|
32
|
+
threadIDs = [threadIDs];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const form = {
|
|
36
|
+
should_archive: archive
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
threadIDs.forEach(id => {
|
|
40
|
+
form[`thread_fbids[${id}]`] = true;
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const res = await defaultFuncs.post(
|
|
44
|
+
"https://www.facebook.com/ajax/mercury/change_archived_status.php",
|
|
45
|
+
ctx.jar,
|
|
46
|
+
form
|
|
47
|
+
).then(utils.parseAndCheckLogin(ctx, defaultFuncs));
|
|
48
|
+
|
|
49
|
+
if (res && res.error) {
|
|
50
|
+
throw res;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
callback(null, { success: true });
|
|
54
|
+
} catch (err) {
|
|
55
|
+
utils.error("changeArchivedStatus", err);
|
|
56
|
+
callback(err);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return returnPromise;
|
|
60
|
+
};
|
|
61
|
+
};
|