fca-nino 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fca-nino might be problematic. Click here for more details.
- package/.gitattributes +2 -0
- package/.travis.yml +6 -0
- package/CHANGELOG.md +2 -0
- package/DOCS.md +1738 -0
- package/LICENSE-MIT +21 -0
- package/README.md +219 -0
- package/index.js +541 -0
- package/package.json +73 -0
- package/replit.nix +5 -0
- package/src/Screenshot.js +83 -0
- package/src/addExternalModule.js +15 -0
- package/src/addUserToGroup.js +77 -0
- package/src/changeAdminStatus.js +47 -0
- package/src/changeArchivedStatus.js +41 -0
- package/src/changeAvt.js +85 -0
- package/src/changeBio.js +65 -0
- package/src/changeBlockedStatus.js +36 -0
- package/src/changeGroupImage.js +106 -0
- package/src/changeNickname.js +45 -0
- package/src/changeThreadColor.js +61 -0
- package/src/changeThreadEmoji.js +41 -0
- package/src/createNewGroup.js +70 -0
- package/src/createPoll.js +59 -0
- package/src/deleteMessage.js +44 -0
- package/src/deleteThread.js +42 -0
- package/src/forwardAttachment.js +47 -0
- package/src/getCurrentUserID.js +7 -0
- package/src/getEmojiUrl.js +27 -0
- package/src/getFriendsList.js +73 -0
- package/src/getThreadHistory.js +537 -0
- package/src/getThreadHistoryDeprecated.js +71 -0
- package/src/getThreadInfo.js +171 -0
- package/src/getThreadInfoDeprecated.js +56 -0
- package/src/getThreadList.js +213 -0
- package/src/getThreadListDeprecated.js +46 -0
- package/src/getThreadPictures.js +59 -0
- package/src/getUserID.js +61 -0
- package/src/getUserInfo.js +66 -0
- package/src/handleFriendRequest.js +46 -0
- package/src/handleMessageRequest.js +47 -0
- package/src/httpGet.js +49 -0
- package/src/httpPost.js +48 -0
- package/src/listenMqtt.js +701 -0
- package/src/logout.js +68 -0
- package/src/markAsDelivered.js +47 -0
- package/src/markAsRead.js +70 -0
- package/src/markAsReadAll.js +40 -0
- package/src/markAsSeen.js +48 -0
- package/src/muteThread.js +45 -0
- package/src/removeUserFromGroup.js +45 -0
- package/src/resolvePhotoUrl.js +36 -0
- package/src/searchForThread.js +42 -0
- package/src/sendMessage.js +328 -0
- package/src/sendTypingIndicator.js +70 -0
- package/src/setMessageReaction.js +109 -0
- package/src/setPostReaction.js +102 -0
- package/src/setTitle.js +70 -0
- package/src/shareContact.js +46 -0
- package/src/threadColors.js +41 -0
- package/src/unfriend.js +42 -0
- package/src/unsendMessage.js +39 -0
- package/test/data/shareAttach.js +146 -0
- package/test/data/something.mov +0 -0
- package/test/data/test.png +0 -0
- package/test/data/test.txt +7 -0
- package/test/example-config.json +18 -0
- package/test/test-page.js +140 -0
- package/test/test.js +385 -0
- package/utils.js +1196 -0
package/DOCS.md
ADDED
@@ -0,0 +1,1738 @@
|
|
1
|
+
# Documentation
|
2
|
+
|
3
|
+
* [`login`](#login)
|
4
|
+
* [`api.addUserToGroup`](#addUserToGroup)
|
5
|
+
* [`api.changeAdminStatus`](#changeAdminStatus)
|
6
|
+
* [`api.changeArchivedStatus`](#changeArchivedStatus)
|
7
|
+
* [`api.changeBlockedStatus`](#changeBlockedStatus)
|
8
|
+
* [`api.changeGroupImage`](#changeGroupImage)
|
9
|
+
* [`api.changeNickname`](#changeNickname)
|
10
|
+
* [`api.changeThreadColor`](#changeThreadColor)
|
11
|
+
* [`api.changeThreadEmoji`](#changeThreadEmoji)
|
12
|
+
* [`api.createNewGroup`](#createNewGroup)
|
13
|
+
* [`api.createPoll`](#createPoll)
|
14
|
+
* [`api.deleteMessage`](#deleteMessage)
|
15
|
+
* [`api.deleteThread`](#deleteThread)
|
16
|
+
* [`api.forwardAttachment`](#forwardAttachment)
|
17
|
+
* [`api.getAppState`](#getAppState)
|
18
|
+
* [`api.getCurrentUserID`](#getCurrentUserID)
|
19
|
+
* [`api.getEmojiUrl`](#getEmojiUrl)
|
20
|
+
* [`api.getFriendsList`](#getFriendsList)
|
21
|
+
* [`api.getThreadHistory`](#getThreadHistory)
|
22
|
+
* [`api.getThreadInfo`](#getThreadInfo)
|
23
|
+
* [`api.getThreadList`](#getThreadList)
|
24
|
+
* [`api.getThreadPictures`](#getThreadPictures)
|
25
|
+
* [`api.getUserID`](#getUserID)
|
26
|
+
* [`api.getUserInfo`](#getUserInfo)
|
27
|
+
* [`api.handleMessageRequest`](#handleMessageRequest)
|
28
|
+
* [`api.listenMqtt`](#listenMqtt)
|
29
|
+
* [`api.logout`](#logout)
|
30
|
+
* [`api.markAsDelivered`](#markAsDelivered)
|
31
|
+
* [`api.markAsRead`](#markAsRead)
|
32
|
+
* [`api.markAsReadAll`](#markAsReadAll)
|
33
|
+
* [`api.markAsSeen`](#markAsSeen)
|
34
|
+
* [`api.muteThread`](#muteThread)
|
35
|
+
* [`api.removeUserFromGroup`](#removeUserFromGroup)
|
36
|
+
* [`api.resolvePhotoUrl`](#resolvePhotoUrl)
|
37
|
+
* [`api.searchForThread`](#searchForThread)
|
38
|
+
* [`api.sendMessage`](#sendMessage)
|
39
|
+
* [`api.sendTypingIndicator`](#sendTypingIndicator)
|
40
|
+
* [`api.setMessageReaction`](#setMessageReaction)
|
41
|
+
* [`api.setOptions`](#setOptions)
|
42
|
+
* [`api.setTitle`](#setTitle)
|
43
|
+
* [`api.threadColors`](#threadColors)
|
44
|
+
* [`api.unsendMessage`](#unsendMessage)
|
45
|
+
|
46
|
+
---------------------------------------
|
47
|
+
|
48
|
+
### Password safety
|
49
|
+
|
50
|
+
**Read this** before you _copy+paste_ examples from below.
|
51
|
+
|
52
|
+
You should not store Facebook password in your scripts.
|
53
|
+
There are few good reasons:
|
54
|
+
* People who are standing behind you may look at your "code" and get your password if it is on the screen
|
55
|
+
* Backups of source files may be readable by someone else. "_There is nothing secret in my code, why should I ever password protect my backups_"
|
56
|
+
* You can't push your code to Github (or any onther service) without removing your password from the file. Remember: Even if you undo your accidential commit with password, Git doesn't delete it, that commit is just not used but is still readable by everybody.
|
57
|
+
* If you change your password in the future (maybe it leaked because _someone_ stored password in source file… oh… well…) you will have to change every occurrence in your scripts
|
58
|
+
|
59
|
+
Preferred method is to have `login.js` that saves `AppState` to a file and then use that file from all your scripts.
|
60
|
+
This way you can put password in your code for a minute, login to facebook and then remove it.
|
61
|
+
|
62
|
+
If you want to be even more safe: _login.js_ can get password with `require("readline")` or with environment variables like this:
|
63
|
+
```js
|
64
|
+
var credentials = {
|
65
|
+
email: process.env.FB_EMAIL,
|
66
|
+
password: process.env.FB_PASSWORD
|
67
|
+
}
|
68
|
+
```
|
69
|
+
```bash
|
70
|
+
FB_EMAIL="john.doe@example.com"
|
71
|
+
FB_PASSWORD="MySuperHardP@ssw0rd"
|
72
|
+
nodejs login.js
|
73
|
+
```
|
74
|
+
|
75
|
+
---------------------------------------
|
76
|
+
|
77
|
+
<a name="login"></a>
|
78
|
+
### login(credentials[, options][, callback])
|
79
|
+
|
80
|
+
This function is returned by `require(...)` and is the main entry point to the API.
|
81
|
+
|
82
|
+
It allows the user to log into facebook given the right credentials.
|
83
|
+
|
84
|
+
Return a Promise that will resolve if logged in successfully, or reject if failed to login. (will not resolve or reject if callback is supplied!)
|
85
|
+
|
86
|
+
If `callback` is supplied:
|
87
|
+
|
88
|
+
* `callback` will be called with a `null` object (for potential errors) and with an object containing all the available functions if logged in successfully.
|
89
|
+
|
90
|
+
* `callback` will be called with an error object if failed to login.
|
91
|
+
|
92
|
+
If `login-approval` error was thrown: Inside error object is `continue` function, you can call that function with 2FA code. The behaviour of this function depends on how you call `login` with:
|
93
|
+
|
94
|
+
* If `callback` is not supplied (using `Promise`), this function will return a `Promise` that behaves like `Promise` received from `login`.
|
95
|
+
|
96
|
+
* If `callback` is supplied, this function will still return a `Promise`, but it will not resolve. Instead, the result is called to `callback`.
|
97
|
+
|
98
|
+
__Arguments__
|
99
|
+
|
100
|
+
* `credentials`: An object containing the fields `email` and `password` used to login, __*or*__ an object containing the field `appState`.
|
101
|
+
* `options`: An object representing options to use when logging in (as described in [api.setOptions](#setOptions)).
|
102
|
+
* `callback(err, api)`: A callback called when login is done (successful or not). `err` is an object containing a field `error`.
|
103
|
+
|
104
|
+
__Example (Email & Password)__
|
105
|
+
|
106
|
+
```js
|
107
|
+
const login = require("fca-unofficial");
|
108
|
+
|
109
|
+
login({email: "FB_EMAIL", password: "FB_PASSWORD"}, (err, api) => {
|
110
|
+
if(err) return console.error(err);
|
111
|
+
// Here you can use the api
|
112
|
+
});
|
113
|
+
```
|
114
|
+
|
115
|
+
__Example (Email & Password then save appState to file)__
|
116
|
+
|
117
|
+
```js
|
118
|
+
const fs = require("fs");
|
119
|
+
const login = require("fca-unofficial");
|
120
|
+
|
121
|
+
login({email: "FB_EMAIL", password: "FB_PASSWORD"}, (err, api) => {
|
122
|
+
if(err) return console.error(err);
|
123
|
+
|
124
|
+
fs.writeFileSync('appstate.json', JSON.stringify(api.getAppState()));
|
125
|
+
});
|
126
|
+
```
|
127
|
+
|
128
|
+
__Example (AppState loaded from file)__
|
129
|
+
|
130
|
+
```js
|
131
|
+
const fs = require("fs");
|
132
|
+
const login = require("fca-unofficial");
|
133
|
+
|
134
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
135
|
+
if(err) return console.error(err);
|
136
|
+
// Here you can use the api
|
137
|
+
});
|
138
|
+
```
|
139
|
+
|
140
|
+
__Login Approvals (2-Factor Auth)__: When you try to login with Login Approvals enabled, your callback will be called with an error `'login-approval'` that has a `continue` function that accepts the approval code as a `string` or a `number`.
|
141
|
+
|
142
|
+
__Example__:
|
143
|
+
|
144
|
+
```js
|
145
|
+
const fs = require("fs");
|
146
|
+
const login = require("fca-unofficial");
|
147
|
+
const readline = require("readline");
|
148
|
+
|
149
|
+
var rl = readline.createInterface({
|
150
|
+
input: process.stdin,
|
151
|
+
output: process.stdout
|
152
|
+
});
|
153
|
+
|
154
|
+
const obj = {email: "FB_EMAIL", password: "FB_PASSWORD"};
|
155
|
+
login(obj, (err, api) => {
|
156
|
+
if(err) {
|
157
|
+
switch (err.error) {
|
158
|
+
case 'login-approval':
|
159
|
+
console.log('Enter code > ');
|
160
|
+
rl.on('line', (line) => {
|
161
|
+
err.continue(line);
|
162
|
+
rl.close();
|
163
|
+
});
|
164
|
+
break;
|
165
|
+
default:
|
166
|
+
console.error(err);
|
167
|
+
}
|
168
|
+
return;
|
169
|
+
}
|
170
|
+
|
171
|
+
// Logged in!
|
172
|
+
});
|
173
|
+
```
|
174
|
+
|
175
|
+
__Review Recent Login__: Sometimes Facebook will ask you to review your recent logins. This means you've recently logged in from a unrecognized location. This will will result in the callback being called with an error `'review-recent-login'` by default. If you wish to automatically approve all recent logins, you can set the option `forceLogin` to `true` in the `loginOptions`.
|
176
|
+
|
177
|
+
|
178
|
+
---------------------------------------
|
179
|
+
|
180
|
+
<a name="addUserToGroup"></a>
|
181
|
+
### api.addUserToGroup(userID, threadID[, callback])
|
182
|
+
|
183
|
+
Adds a user (or array of users) to a group chat.
|
184
|
+
|
185
|
+
__Arguments__
|
186
|
+
|
187
|
+
* `userID`: User ID or array of user IDs.
|
188
|
+
* `threadID`: Group chat ID.
|
189
|
+
* `callback(err)`: A callback called when the query is done (either with an error or with no arguments).
|
190
|
+
|
191
|
+
---------------------------------------
|
192
|
+
|
193
|
+
<a name="changeAdminStatus"></a>
|
194
|
+
### api.changeAdminStatus(threadID, adminIDs, adminStatus)
|
195
|
+
|
196
|
+
Given a adminID, or an array of adminIDs, will set the admin status of the user(s) to `adminStatus`.
|
197
|
+
|
198
|
+
__Arguments__
|
199
|
+
* `threadID`: ID of a group chat (can't use in one-to-one conversations)
|
200
|
+
* `adminIDs`: The id(s) of users you wish to admin/unadmin (string or an array).
|
201
|
+
* `adminStatus`: Boolean indicating whether the user(s) should be promoted to admin (`true`) or demoted to a regular user (`false`).
|
202
|
+
|
203
|
+
__Example__
|
204
|
+
|
205
|
+
```js
|
206
|
+
const fs = require("fs");
|
207
|
+
const login = require("fca-unofficial");
|
208
|
+
|
209
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, async function(err, api) {
|
210
|
+
if (err) return console.error(err);
|
211
|
+
|
212
|
+
let threadID = "0000000000000000";
|
213
|
+
let newAdmins = ["111111111111111", "222222222222222"];
|
214
|
+
await api.changeAdminStatus(threadID, newAdmins, true);
|
215
|
+
|
216
|
+
let adminToRemove = "333333333333333";
|
217
|
+
await api.changeAdminStatus(threadID, adminToRemove, false);
|
218
|
+
|
219
|
+
});
|
220
|
+
|
221
|
+
```
|
222
|
+
|
223
|
+
---------------------------------------
|
224
|
+
|
225
|
+
<a name="changeArchivedStatus"></a>
|
226
|
+
### api.changeArchivedStatus(threadOrThreads, archive[, callback])
|
227
|
+
|
228
|
+
Given a threadID, or an array of threadIDs, will set the archive status of the threads to `archive`. Archiving a thread will hide it from the logged-in user's inbox until the next time a message is sent or received.
|
229
|
+
|
230
|
+
__Arguments__
|
231
|
+
* `threadOrThreads`: The id(s) of the threads you wish to archive/unarchive.
|
232
|
+
* `archive`: Boolean indicating the new archive status to assign to the thread(s).
|
233
|
+
* `callback(err)`: A callback called when the query is done (either with an error or null).
|
234
|
+
|
235
|
+
__Example__
|
236
|
+
|
237
|
+
```js
|
238
|
+
const fs = require("fs");
|
239
|
+
const login = require("fca-unofficial");
|
240
|
+
|
241
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
242
|
+
if(err) return console.error(err);
|
243
|
+
|
244
|
+
api.changeArchivedStatus("000000000000000", true, (err) => {
|
245
|
+
if(err) return console.error(err);
|
246
|
+
});
|
247
|
+
});
|
248
|
+
```
|
249
|
+
|
250
|
+
---------------------------------------
|
251
|
+
|
252
|
+
<a name="changeBlockedStatus"></a>
|
253
|
+
### api.changeBlockedStatus(userID, block[, callback])
|
254
|
+
|
255
|
+
Prevents a user from privately contacting you. (Messages in a group chat will still be seen by both parties).
|
256
|
+
|
257
|
+
__Arguments__
|
258
|
+
|
259
|
+
* `userID`: User ID.
|
260
|
+
* `block`: Boolean indicating whether to block or unblock the user (true for block).
|
261
|
+
* `callback(err)`: A callback called when the query is done (either with an error or with no arguments).
|
262
|
+
|
263
|
+
---------------------------------------
|
264
|
+
|
265
|
+
<a name="changeGroupImage"></a>
|
266
|
+
### api.changeGroupImage(image, threadID[, callback])
|
267
|
+
|
268
|
+
Will change the group chat's image to the given image.
|
269
|
+
|
270
|
+
__Arguments__
|
271
|
+
* `image`: File stream of image.
|
272
|
+
* `threadID`: String representing the ID of the thread.
|
273
|
+
* `callback(err)`: A callback called when the change is done (either with an error or null).
|
274
|
+
|
275
|
+
__Example__
|
276
|
+
|
277
|
+
```js
|
278
|
+
const fs = require("fs");
|
279
|
+
const login = require("fca-unofficial");
|
280
|
+
|
281
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
282
|
+
if(err) return console.error(err);
|
283
|
+
|
284
|
+
api.changeGroupImage(fs.createReadStream("./avatar.png"), "000000000000000", (err) => {
|
285
|
+
if(err) return console.error(err);
|
286
|
+
});
|
287
|
+
});
|
288
|
+
```
|
289
|
+
|
290
|
+
---------------------------------------
|
291
|
+
|
292
|
+
<a name="changeNickname"></a>
|
293
|
+
### api.changeNickname(nickname, threadID, participantID[, callback])
|
294
|
+
|
295
|
+
Will change the thread user nickname to the one provided.
|
296
|
+
|
297
|
+
__Arguments__
|
298
|
+
* `nickname`: String containing a nickname. Leave empty to reset nickname.
|
299
|
+
* `threadID`: String representing the ID of the thread.
|
300
|
+
* `participantID`: String representing the ID of the user.
|
301
|
+
* `callback(err)`: An optional callback called when the change is done (either with an error or null).
|
302
|
+
|
303
|
+
__Example__
|
304
|
+
|
305
|
+
```js
|
306
|
+
const fs = require("fs");
|
307
|
+
const login = require("fca-unofficial");
|
308
|
+
|
309
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
310
|
+
if(err) return console.error(err);
|
311
|
+
|
312
|
+
api.changeNickname("Example", "000000000000000", "000000000000000", (err) => {
|
313
|
+
if(err) return console.error(err);
|
314
|
+
});
|
315
|
+
});
|
316
|
+
```
|
317
|
+
|
318
|
+
---------------------------------------
|
319
|
+
|
320
|
+
<a name="changeThreadColor"></a>
|
321
|
+
### api.changeThreadColor(color, threadID[, callback])
|
322
|
+
|
323
|
+
Will change the thread color to the given hex string color ("#0000ff"). Set it
|
324
|
+
to empty string if you want the default.
|
325
|
+
|
326
|
+
Note: the color needs to start with a "#".
|
327
|
+
|
328
|
+
__Arguments__
|
329
|
+
* `color`: String representing a theme ID (a list of theme ID can be found at `api.threadColors`).
|
330
|
+
* `threadID`: String representing the ID of the thread.
|
331
|
+
* `callback(err)`: A callback called when the change is done (either with an error or null).
|
332
|
+
|
333
|
+
__Example__
|
334
|
+
|
335
|
+
```js
|
336
|
+
const fs = require("fs");
|
337
|
+
const login = require("fca-unofficial");
|
338
|
+
|
339
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
340
|
+
if(err) return console.error(err);
|
341
|
+
|
342
|
+
api.changeThreadColor("#0000ff", "000000000000000", (err) => {
|
343
|
+
if(err) return console.error(err);
|
344
|
+
});
|
345
|
+
});
|
346
|
+
```
|
347
|
+
|
348
|
+
---------------------------------------
|
349
|
+
|
350
|
+
<a name="changeThreadEmoji"></a>
|
351
|
+
### api.changeThreadEmoji(emoji, threadID[, callback])
|
352
|
+
|
353
|
+
Will change the thread emoji to the one provided.
|
354
|
+
|
355
|
+
Note: The UI doesn't play nice with all emoji.
|
356
|
+
|
357
|
+
__Arguments__
|
358
|
+
* `emoji`: String containing a single emoji character.
|
359
|
+
* `threadID`: String representing the ID of the thread.
|
360
|
+
* `callback(err)`: A callback called when the change is done (either with an error or null).
|
361
|
+
|
362
|
+
__Example__
|
363
|
+
|
364
|
+
```js
|
365
|
+
const fs = require("fs");
|
366
|
+
const login = require("fca-unofficial");
|
367
|
+
|
368
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
369
|
+
if(err) return console.error(err);
|
370
|
+
|
371
|
+
api.changeThreadEmoji("💯", "000000000000000", (err) => {
|
372
|
+
if(err) return console.error(err);
|
373
|
+
});
|
374
|
+
});
|
375
|
+
```
|
376
|
+
|
377
|
+
---------------------------------------
|
378
|
+
|
379
|
+
<a name="createNewGroup"></a>
|
380
|
+
### api.createNewGroup(participantIDs[, groupTitle][, callback])
|
381
|
+
|
382
|
+
Create a new group chat.
|
383
|
+
|
384
|
+
__Arguments__
|
385
|
+
* `participantIDs`: An array containing participant IDs. (*Length must be >= 2*)
|
386
|
+
* `groupTitle`: The title of the new group chat.
|
387
|
+
* `callback(err, threadID)`: A callback called when created.
|
388
|
+
|
389
|
+
---------------------------------------
|
390
|
+
|
391
|
+
<a name="createPoll"></a>
|
392
|
+
### api.createPoll(title, threadID[, options][, callback]) (*temporary deprecated because Facebook is updating this feature*)
|
393
|
+
|
394
|
+
Creates a poll with the specified title and optional poll options, which can also be initially selected by the logged-in user.
|
395
|
+
|
396
|
+
__Arguments__
|
397
|
+
* `title`: String containing a title for the poll.
|
398
|
+
* `threadID`: String representing the ID of the thread.
|
399
|
+
* `options`: An optional `string : bool` dictionary to specify initial poll options and their initial states (selected/not selected), respectively.
|
400
|
+
* `callback(err)`: An optional callback called when the poll is posted (either with an error or null) - can omit the `options` parameter and use this as the third parameter if desired.
|
401
|
+
|
402
|
+
__Example__
|
403
|
+
|
404
|
+
```js
|
405
|
+
const fs = require("fs");
|
406
|
+
const login = require("fca-unofficial");
|
407
|
+
|
408
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
409
|
+
if(err) return console.error(err);
|
410
|
+
|
411
|
+
api.createPoll("Example Poll", "000000000000000", {
|
412
|
+
"Option 1": false,
|
413
|
+
"Option 2": true
|
414
|
+
}, (err) => {
|
415
|
+
if(err) return console.error(err);
|
416
|
+
});
|
417
|
+
});
|
418
|
+
```
|
419
|
+
|
420
|
+
---------------------------------------
|
421
|
+
|
422
|
+
<a name="deleteMessage"></a>
|
423
|
+
### api.deleteMessage(messageOrMessages[, callback])
|
424
|
+
|
425
|
+
Takes a messageID or an array of messageIDs and deletes the corresponding message.
|
426
|
+
|
427
|
+
__Arguments__
|
428
|
+
* `messageOrMessages`: A messageID string or messageID string array
|
429
|
+
* `callback(err)`: A callback called when the query is done (either with an error or null).
|
430
|
+
|
431
|
+
__Example__
|
432
|
+
```js
|
433
|
+
const fs = require("fs");
|
434
|
+
const login = require("fca-unofficial");
|
435
|
+
|
436
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
437
|
+
if(err) return console.error(err);
|
438
|
+
|
439
|
+
api.listen((err, message) => {
|
440
|
+
if(message.body) {
|
441
|
+
api.sendMessage(message.body, message.threadID, (err, messageInfo) => {
|
442
|
+
if(err) return console.error(err);
|
443
|
+
|
444
|
+
api.deleteMessage(messageInfo.messageID);
|
445
|
+
});
|
446
|
+
}
|
447
|
+
});
|
448
|
+
});
|
449
|
+
```
|
450
|
+
|
451
|
+
---------------------------------------
|
452
|
+
|
453
|
+
<a name="deleteThread"></a>
|
454
|
+
### api.deleteThread(threadOrThreads[, callback])
|
455
|
+
|
456
|
+
Given a threadID, or an array of threadIDs, will delete the threads from your account. Note that this does *not* remove the messages from Facebook's servers - anyone who hasn't deleted the thread can still view all of the messages.
|
457
|
+
|
458
|
+
__Arguments__
|
459
|
+
|
460
|
+
* `threadOrThreads` - The id(s) of the threads you wish to remove from your account.
|
461
|
+
* `callback(err)` - A callback called when the operation is done, maybe with an object representing an error.
|
462
|
+
|
463
|
+
__Example__
|
464
|
+
|
465
|
+
```js
|
466
|
+
const fs = require("fs");
|
467
|
+
const login = require("fca-unofficial");
|
468
|
+
|
469
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
470
|
+
if(err) return console.error(err);
|
471
|
+
|
472
|
+
api.deleteThread("000000000000000", (err) => {
|
473
|
+
if(err) return console.error(err);
|
474
|
+
});
|
475
|
+
});
|
476
|
+
```
|
477
|
+
|
478
|
+
---------------------------------------
|
479
|
+
|
480
|
+
<a name="forwardAttachment"></a>
|
481
|
+
### api.forwardAttachment(attachmentID, userOrUsers[, callback])
|
482
|
+
|
483
|
+
Forwards corresponding attachment to given userID or to every user from an array of userIDs
|
484
|
+
|
485
|
+
__Arguments__
|
486
|
+
* `attachmentID`: The ID field in the attachment object. Recorded audio cannot be forwarded.
|
487
|
+
* `userOrUsers`: A userID string or usersID string array
|
488
|
+
* `callback(err)`: A callback called when the query is done (either with an error or null).
|
489
|
+
|
490
|
+
---------------------------------------
|
491
|
+
|
492
|
+
<a name="getAppState"></a>
|
493
|
+
### api.getAppState()
|
494
|
+
|
495
|
+
Returns current appState which can be saved to a file or stored in a variable.
|
496
|
+
|
497
|
+
---------------------------------------
|
498
|
+
|
499
|
+
<a name="getCurrentUserID"></a>
|
500
|
+
### api.getCurrentUserID()
|
501
|
+
|
502
|
+
Returns the currently logged-in user's Facebook user ID.
|
503
|
+
|
504
|
+
---------------------------------------
|
505
|
+
|
506
|
+
<a name="getEmojiUrl"></a>
|
507
|
+
### api.getEmojiUrl(c, size[, pixelRatio])
|
508
|
+
|
509
|
+
Returns the URL to a Facebook Messenger-style emoji image asset.
|
510
|
+
|
511
|
+
__note__: This function will return a URL regardless of whether the image at the URL actually exists.
|
512
|
+
This can happen if, for example, Messenger does not have an image asset for the requested emoji.
|
513
|
+
|
514
|
+
__Arguments__
|
515
|
+
|
516
|
+
* `c` - The emoji character
|
517
|
+
* `size` - The width and height of the emoji image; supported sizes are 32, 64, and 128
|
518
|
+
* `pixelRatio` - The pixel ratio of the emoji image; supported ratios are '1.0' and '1.5' (default is '1.0')
|
519
|
+
|
520
|
+
__Example__
|
521
|
+
|
522
|
+
```js
|
523
|
+
const fs = require("fs");
|
524
|
+
const login = require("fca-unofficial");
|
525
|
+
|
526
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
527
|
+
if(err) return console.error(err);
|
528
|
+
|
529
|
+
// Prints https://static.xx.fbcdn.net/images/emoji.php/v8/z9c/1.0/128/1f40d.png
|
530
|
+
console.log('Snake emoji, 128px (128x128 with pixel ratio of 1.0');
|
531
|
+
console.log(api.getEmojiUrl('\ud83d\udc0d', 128));
|
532
|
+
|
533
|
+
// Prints https://static.xx.fbcdn.net/images/emoji.php/v8/ze1/1.5/128/1f40d.png
|
534
|
+
console.log('Snake emoji, 192px (128x128 with pixel ratio of 1.5');
|
535
|
+
console.log(api.getEmojiUrl('\ud83d\udc0d', 128, '1.5'));
|
536
|
+
});
|
537
|
+
```
|
538
|
+
|
539
|
+
---------------------------------------
|
540
|
+
|
541
|
+
<a name="getFriendsList"></a>
|
542
|
+
### api.getFriendsList(callback)
|
543
|
+
|
544
|
+
Returns an array of objects with some information about your friends.
|
545
|
+
|
546
|
+
__Arguments__
|
547
|
+
|
548
|
+
* `callback(err, arr)` - A callback called when the query is done (either with an error or with an confirmation object). `arr` is an array of objects with the following fields: `alternateName`, `firstName`, `gender`, `userID`, `isFriend`, `fullName`, `profilePicture`, `type`, `profileUrl`, `vanity`, `isBirthday`.
|
549
|
+
|
550
|
+
__Example__
|
551
|
+
|
552
|
+
```js
|
553
|
+
const fs = require("fs");
|
554
|
+
const login = require("fca-unofficial");
|
555
|
+
|
556
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
557
|
+
if(err) return console.error(err);
|
558
|
+
|
559
|
+
api.getFriendsList((err, data) => {
|
560
|
+
if(err) return console.error(err);
|
561
|
+
|
562
|
+
console.log(data.length);
|
563
|
+
});
|
564
|
+
});
|
565
|
+
```
|
566
|
+
|
567
|
+
---------------------------------------
|
568
|
+
|
569
|
+
<a name="getThreadHistory"></a>
|
570
|
+
### api.getThreadHistory(threadID, amount, timestamp, callback)
|
571
|
+
|
572
|
+
Takes a threadID, number of messages, a timestamp, and a callback.
|
573
|
+
|
574
|
+
__note__: if you're getting a 500 error, it's possible that you're requesting too many messages. Try reducing that number and see if that works.
|
575
|
+
|
576
|
+
__Arguments__
|
577
|
+
* `threadID`: A threadID corresponding to the target chat
|
578
|
+
* `amount`: The amount of messages to *request*
|
579
|
+
* `timestamp`: Used to described the time of the most recent message to load. If timestamp is `undefined`, facebook will load the most recent messages.
|
580
|
+
* `callback(error, history)`: If error is null, history will contain an array of message objects.
|
581
|
+
|
582
|
+
__Example__
|
583
|
+
|
584
|
+
To load 50 messages at a time, we can use `undefined` as the timestamp to retrieve the most recent messages and use the timestamp of the earliest message to load the next 50.
|
585
|
+
|
586
|
+
```js
|
587
|
+
var timestamp = undefined;
|
588
|
+
|
589
|
+
function loadNextThreadHistory(api){
|
590
|
+
api.getThreadHistory(threadID, 50, timestamp, (err, history) => {
|
591
|
+
if(err) return console.error(err);
|
592
|
+
|
593
|
+
/*
|
594
|
+
Since the timestamp is from a previous loaded message,
|
595
|
+
that message will be included in this history so we can discard it unless it is the first load.
|
596
|
+
*/
|
597
|
+
if(timestamp != undefined) history.pop();
|
598
|
+
|
599
|
+
/*
|
600
|
+
Handle message history
|
601
|
+
*/
|
602
|
+
|
603
|
+
timestamp = history[0].timestamp;
|
604
|
+
});
|
605
|
+
}
|
606
|
+
```
|
607
|
+
|
608
|
+
---------------------------------------
|
609
|
+
|
610
|
+
<a name="getThreadInfo"></a>
|
611
|
+
### api.getThreadInfo(threadID[, callback])
|
612
|
+
|
613
|
+
Takes a threadID and a callback. Works for both single-user and group threads.
|
614
|
+
|
615
|
+
__Arguments__
|
616
|
+
* `threadID`: A threadID corresponding to the target thread.
|
617
|
+
* `callback(err, info)`: If `err` is `null`, `info` will contain the following properties:
|
618
|
+
|
619
|
+
| Key | Description |
|
620
|
+
|----------|:-------------:|
|
621
|
+
| threadID | ID of the thread |
|
622
|
+
| participantIDs | Array of user IDs in the thread |
|
623
|
+
| threadName | Name of the thread. Usually the name of the user. In group chats, this will be empty if the name of the group chat is unset. |
|
624
|
+
| userInfo | An array contains info of members, which has the same structure as [`getUserInfo`](#getUserInfo), but add a key `id`, contain ID of member currently at. |
|
625
|
+
| nicknames | Map of nicknames for members of the thread. If there are no nicknames set, this will be null. |
|
626
|
+
| unreadCount | Number of unread messages |
|
627
|
+
| messageCount | Number of messages |
|
628
|
+
| imageSrc | URL to the group chat photo. Null if unset or a 1-1 thread. |
|
629
|
+
| timestamp | Timestamp of last activity |
|
630
|
+
| muteUntil | Timestamp at which the thread will no longer be muted. The timestamp will be -1 if the thread is muted indefinitely or null if the thread is not muted. |
|
631
|
+
| isGroup | boolean, true if this thread is a group thread (more than 2 participants). |
|
632
|
+
| isSubscribed | |
|
633
|
+
| folder | The folder that the thread is in. Can be one of: <ul><li>'inbox'</li><li>'archive'</li></ul> |
|
634
|
+
| isArchived | True if the thread is archived, false if not |
|
635
|
+
| cannotReplyReason | If you cannot reply to this thread, this will be a string stating why. Otherwise it will be null. |
|
636
|
+
| lastReadTimestamp | Timestamp of the last message that is marked as 'read' by the current user. |
|
637
|
+
| emoji | Object with key 'emoji' whose value is the emoji unicode character. Null if unset. |
|
638
|
+
| color | String form of the custom color in hexadecimal form. |
|
639
|
+
| adminIDs | Array of user IDs of the admins of the thread. Empty array if unset. |
|
640
|
+
| approvalMode | `true` or `false`, used to check if this group requires admin approval to add users |
|
641
|
+
| approvalQueue | Array of object that has the following keys: <ul><li>`inviterID`: ID of the user invited the person to the group</li><li>`requesterID`: ID of the person waiting to be approved</li><li>`timestamp`: Request timestamp</li></ul> |
|
642
|
+
|
643
|
+
---------------------------------------
|
644
|
+
|
645
|
+
<a name="getThreadList"></a>
|
646
|
+
### api.getThreadList(limit, timestamp, tags, callback)
|
647
|
+
|
648
|
+
Returns information about the user's threads.
|
649
|
+
|
650
|
+
__Arguments__
|
651
|
+
|
652
|
+
* `limit`: Limit the number of threads to fetch.
|
653
|
+
* `timestamp`: Request threads *before* this date. `null` means *now*
|
654
|
+
* `tags`: An array describing which folder to fetch. It should be one of these:
|
655
|
+
- `["INBOX"]` *(same as `[]`)*
|
656
|
+
- `["ARCHIVED"]`
|
657
|
+
- `["PENDING"]`
|
658
|
+
- `["OTHER"]`
|
659
|
+
- `["INBOX", "unread"]`
|
660
|
+
- `["ARCHIVED", "unread"]`
|
661
|
+
- `["PENDING", "unread"]`
|
662
|
+
- `["OTHER", "unread"]`
|
663
|
+
|
664
|
+
*if you find something new, let us know*
|
665
|
+
|
666
|
+
* `callback(err, list)`: Callback called when the query is done (either with an error or with a proper result). `list` is an *array* with objects with the following properties:
|
667
|
+
|
668
|
+
__Thread list__
|
669
|
+
|
670
|
+
| Key | Description |
|
671
|
+
|----------------------|-------------------------------------------------------------|
|
672
|
+
| threadID | ID of the thread |
|
673
|
+
| name | The name of the thread |
|
674
|
+
| unreadCount | Amount of unread messages in thread |
|
675
|
+
| messageCount | Amount of messages in thread |
|
676
|
+
| imageSrc | Link to the thread's image or `null` |
|
677
|
+
| emoji | The default emoji in thread (classic like is `null`) |
|
678
|
+
| color | Thread's message color in `RRGGBB` (default blue is `null`) |
|
679
|
+
| nicknames | An array of `{"userid": "1234", "nickname": "John Doe"}` |
|
680
|
+
| muteUntil | Timestamp until the mute expires or `null` |
|
681
|
+
| participants | An array of participants. See below |
|
682
|
+
| adminIDs | An array of thread admin IDs |
|
683
|
+
| folder | `INBOX`, `ARCHIVED`, `PENDING` or `OTHER` |
|
684
|
+
| isGroup | `true` or `false` |
|
685
|
+
| customizationEnabled | `false` in one-to-one conversations with `Page` or `ReducedMessagingActor` |
|
686
|
+
| participantAddMode | currently `"ADD"` for groups and `null` otherwise |
|
687
|
+
| reactionsMuteMode | `REACTIONS_NOT_MUTED` or `REACTIONS_MUTED` |
|
688
|
+
| mentionsMuteMode | `MENTIONS_NOT_MUTED` or `MENTIONS_MUTED` |
|
689
|
+
| isArchived | `true` or `false` |
|
690
|
+
| isSubscribed | `true` or `false` |
|
691
|
+
| timestamp | timestamp in miliseconds |
|
692
|
+
| snippet | Snippet's text message |
|
693
|
+
| snippetAttachments | Attachments in snippet |
|
694
|
+
| snippetSender | ID of snippet sender |
|
695
|
+
| lastMessageTimestamp | timestamp in milliseconds |
|
696
|
+
| lastReadTimestamp | timestamp in milliseconds or `null` |
|
697
|
+
| cannotReplyReason | `null`, `"RECIPIENTS_NOT_LOADABLE"` or `"BLOCKED"` |
|
698
|
+
| approvalMode | `true` or `false`, used to check if this group requires admin approval to add users |
|
699
|
+
|
700
|
+
__`participants` format__
|
701
|
+
|
702
|
+
`accountType` is one of the following:
|
703
|
+
- `"User"`
|
704
|
+
- `"Page"`
|
705
|
+
- `"UnavailableMessagingActor"`
|
706
|
+
- `"ReducedMessagingActor"`
|
707
|
+
|
708
|
+
(*there might be more*)
|
709
|
+
|
710
|
+
<table>
|
711
|
+
<tr>
|
712
|
+
<th>Account type</th>
|
713
|
+
<th>Key</th>
|
714
|
+
<th>Description</th>
|
715
|
+
</tr>
|
716
|
+
<tr>
|
717
|
+
<td rowspan="12"><code>"User"</code></td>
|
718
|
+
<td>userID</td>
|
719
|
+
<td>ID of user</td>
|
720
|
+
</tr>
|
721
|
+
<tr>
|
722
|
+
<td>name</td>
|
723
|
+
<td>Full name of user</td>
|
724
|
+
</tr>
|
725
|
+
<tr>
|
726
|
+
<td>shortName</td>
|
727
|
+
<td>Short name of user (most likely first name)</td>
|
728
|
+
</tr>
|
729
|
+
<tr>
|
730
|
+
<td>gender</td>
|
731
|
+
<td>Either
|
732
|
+
<code>"MALE"</code>,
|
733
|
+
<code>"FEMALE"</code>,
|
734
|
+
<code>"NEUTER"</code> or
|
735
|
+
<code>"UNKNOWN"</code>
|
736
|
+
</td>
|
737
|
+
</tr>
|
738
|
+
<tr>
|
739
|
+
<td>url</td>
|
740
|
+
<td>URL of the user's Facebook profile</td>
|
741
|
+
</tr>
|
742
|
+
<tr>
|
743
|
+
<td>profilePicture</td>
|
744
|
+
<td>URL of the profile picture</td>
|
745
|
+
</tr>
|
746
|
+
<tr>
|
747
|
+
<td>username</td>
|
748
|
+
<td>Username of user or
|
749
|
+
<code>null</code>
|
750
|
+
</td>
|
751
|
+
</tr>
|
752
|
+
<tr>
|
753
|
+
<td>isViewerFriend</td>
|
754
|
+
<td>Is the user a friend of you?</td>
|
755
|
+
</tr>
|
756
|
+
<tr>
|
757
|
+
<td>isMessengerUser</td>
|
758
|
+
<td>Does the user use Messenger?</td>
|
759
|
+
</tr>
|
760
|
+
<tr>
|
761
|
+
<td>isVerified</td>
|
762
|
+
<td>Is the user verified? (Little blue tick mark)</td>
|
763
|
+
</tr>
|
764
|
+
<tr>
|
765
|
+
<td>isMessageBlockedByViewer</td>
|
766
|
+
<td>Is the user blocking messages from you?</td>
|
767
|
+
</tr>
|
768
|
+
<tr>
|
769
|
+
<td>isViewerCoworker</td>
|
770
|
+
<td>Is the user your coworker?
|
771
|
+
</td>
|
772
|
+
</tr>
|
773
|
+
|
774
|
+
<tr>
|
775
|
+
<td rowspan="10"><code>"Page"</code></td>
|
776
|
+
<td>userID</td>
|
777
|
+
<td>ID of the page</td>
|
778
|
+
</tr>
|
779
|
+
<tr>
|
780
|
+
<td>name</td>
|
781
|
+
<td>Name of the fanpage</td>
|
782
|
+
</tr>
|
783
|
+
<tr>
|
784
|
+
<td>url</td>
|
785
|
+
<td>URL of the fanpage</td>
|
786
|
+
</tr>
|
787
|
+
<tr>
|
788
|
+
<td>profilePicture</td>
|
789
|
+
<td>URL of the profile picture</td>
|
790
|
+
</tr>
|
791
|
+
<tr>
|
792
|
+
<td>username</td>
|
793
|
+
<td>Username of user or
|
794
|
+
<code>null</code>
|
795
|
+
</td>
|
796
|
+
</tr>
|
797
|
+
<tr>
|
798
|
+
<td>acceptsMessengerUserFeedback</td>
|
799
|
+
<td></td>
|
800
|
+
</tr>
|
801
|
+
<tr>
|
802
|
+
<td>isMessengerUser</td>
|
803
|
+
<td>Does the fanpage use Messenger?</td>
|
804
|
+
</tr>
|
805
|
+
<tr>
|
806
|
+
<td>isVerified</td>
|
807
|
+
<td>Is the fanpage verified? (Little blue tick mark)</td>
|
808
|
+
</tr>
|
809
|
+
<tr>
|
810
|
+
<td>isMessengerPlatformBot</td>
|
811
|
+
<td>Is the fanpage a bot</td>
|
812
|
+
</tr>
|
813
|
+
<tr>
|
814
|
+
<td>isMessageBlockedByViewer</td>
|
815
|
+
<td>Is the fanpage blocking messages from you?</td>
|
816
|
+
</tr>
|
817
|
+
|
818
|
+
<tr>
|
819
|
+
<td rowspan="7"><code>"ReducedMessagingActor"</code><br />(account requres verification,<br />messages are hidden)</td>
|
820
|
+
<td>userID</td>
|
821
|
+
<td>ID of the user</td>
|
822
|
+
</tr>
|
823
|
+
<tr>
|
824
|
+
<td>name</td>
|
825
|
+
<td>Name of the user</td>
|
826
|
+
</tr>
|
827
|
+
<tr>
|
828
|
+
<td>url</td>
|
829
|
+
<td>
|
830
|
+
<code>null</code>
|
831
|
+
</td>
|
832
|
+
</tr>
|
833
|
+
<tr>
|
834
|
+
<td>profilePicture</td>
|
835
|
+
<td>URL of the default Facebook profile picture</td>
|
836
|
+
</tr>
|
837
|
+
<tr>
|
838
|
+
<td>username</td>
|
839
|
+
<td>Username of user</td>
|
840
|
+
</td>
|
841
|
+
</tr>
|
842
|
+
<tr>
|
843
|
+
<td>acceptsMessengerUserFeedback</td>
|
844
|
+
<td></td>
|
845
|
+
</tr>
|
846
|
+
<tr>
|
847
|
+
<td>isMessageBlockedByViewer</td>
|
848
|
+
<td>Is the user blocking messages from you?</td>
|
849
|
+
</tr>
|
850
|
+
<tr>
|
851
|
+
<td rowspan="7"><code>"UnavailableMessagingActor"</code><br />(account disabled/removed)</td>
|
852
|
+
<td>userID</td>
|
853
|
+
<td>ID of the user</td>
|
854
|
+
</tr>
|
855
|
+
<tr>
|
856
|
+
<td>name</td>
|
857
|
+
<td><em>Facebook User</em> in user's language</td>
|
858
|
+
</tr>
|
859
|
+
<tr>
|
860
|
+
<td>url</td>
|
861
|
+
<td><code>null</code></td>
|
862
|
+
</tr>
|
863
|
+
<tr>
|
864
|
+
<td>profilePicture</td>
|
865
|
+
<td>URL of the default **male** Facebook profile picture</td>
|
866
|
+
</tr>
|
867
|
+
<tr>
|
868
|
+
<td>username</td>
|
869
|
+
<td><code>null</code></td>
|
870
|
+
</tr>
|
871
|
+
<tr>
|
872
|
+
<td>acceptsMessengerUserFeedback</td>
|
873
|
+
<td></td>
|
874
|
+
</tr>
|
875
|
+
<tr>
|
876
|
+
<td>isMessageBlockedByViewer</td>
|
877
|
+
<td>Is the user blocking messages from you?</td>
|
878
|
+
</tr>
|
879
|
+
</table>
|
880
|
+
|
881
|
+
|
882
|
+
In a case that some account type is not supported, we return just this *(but you can't rely on it)* and log a warning to the console:
|
883
|
+
|
884
|
+
| Key | Description |
|
885
|
+
|--------------|-------------------------|
|
886
|
+
| accountType | type, can be anything |
|
887
|
+
| userID | ID of the account |
|
888
|
+
| name | Name of the account |
|
889
|
+
|
890
|
+
|
891
|
+
---------------------------------------
|
892
|
+
|
893
|
+
<a name="getThreadPictures"></a>
|
894
|
+
### api.getThreadPictures(threadID, offset, limit, callback)
|
895
|
+
|
896
|
+
Returns pictures sent in the thread.
|
897
|
+
|
898
|
+
__Arguments__
|
899
|
+
|
900
|
+
* `threadID`: A threadID corresponding to the target chat
|
901
|
+
* `offset`: Start index of picture to retrieve, where 0 is the most recent picture
|
902
|
+
* `limit`: Number of pictures to get, incrementing from the offset index
|
903
|
+
* `callback(err, arr)`: A callback called when the query is done (either with an error or with an confirmation object). `arr` is an array of objects with `uri`, `width`, and `height`.
|
904
|
+
|
905
|
+
---------------------------------------
|
906
|
+
|
907
|
+
<a name="getUserID"></a>
|
908
|
+
### api.getUserID(name, callback)
|
909
|
+
|
910
|
+
Given the full name or vanity name of a Facebook user, event, page, group or app, the call will perform a Facebook Graph search and return all corresponding IDs (order determined by Facebook).
|
911
|
+
|
912
|
+
__Arguments__
|
913
|
+
|
914
|
+
* `name` - A string being the name of the item you're looking for.
|
915
|
+
* `callback(err, obj)` - A callback called when the search is done (either with an error or with the resulting object). `obj` is an array which contains all of the items that facebook graph search found, ordered by "importance". Each item in the array has the following properties: `userID`,`photoUrl`,`indexRank`, `name`, `isVerified`, `profileUrl`, `category`, `score`, `type` (type is generally user, group, page, event or app).
|
916
|
+
|
917
|
+
__Example__
|
918
|
+
|
919
|
+
```js
|
920
|
+
const fs = require("fs");
|
921
|
+
const login = require("fca-unofficial");
|
922
|
+
|
923
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
924
|
+
if(err) return console.error(err);
|
925
|
+
|
926
|
+
api.getUserID("Marc Zuckerbot", (err, data) => {
|
927
|
+
if(err) return console.error(err);
|
928
|
+
|
929
|
+
// Send the message to the best match (best by Facebook's criteria)
|
930
|
+
var msg = "Hello!"
|
931
|
+
var threadID = data[0].userID;
|
932
|
+
api.sendMessage(msg, threadID);
|
933
|
+
});
|
934
|
+
});
|
935
|
+
```
|
936
|
+
|
937
|
+
---------------------------------------
|
938
|
+
|
939
|
+
<a name="getUserInfo"></a>
|
940
|
+
### api.getUserInfo(ids, callback)
|
941
|
+
|
942
|
+
Will get some information about the given users.
|
943
|
+
|
944
|
+
__Arguments__
|
945
|
+
|
946
|
+
* `ids` - Either a string/number for one ID or an array of strings/numbers for a batched query.
|
947
|
+
* `callback(err, obj)` - A callback called when the query is done (either with an error or with an confirmation object). `obj` is a mapping from userId to another object containing the following properties: `name`, `firstName`, `vanity` (user's chosen facebook handle, if any), `thumbSrc`, `profileUrl`, `gender`, `type` (type is generally user, group, page, event or app), `isFriend`, `isBirthday`, `searchTokens`, `alternateName`.
|
948
|
+
|
949
|
+
__Example__
|
950
|
+
|
951
|
+
```js
|
952
|
+
const fs = require("fs");
|
953
|
+
const login = require("fca-unofficial");
|
954
|
+
|
955
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
956
|
+
if(err) return console.error(err);
|
957
|
+
|
958
|
+
api.getUserInfo([1, 2, 3, 4], (err, ret) => {
|
959
|
+
if(err) return console.error(err);
|
960
|
+
|
961
|
+
for(var prop in ret) {
|
962
|
+
if(ret.hasOwnProperty(prop) && ret[prop].isBirthday) {
|
963
|
+
api.sendMessage("Happy birthday :)", prop);
|
964
|
+
}
|
965
|
+
}
|
966
|
+
});
|
967
|
+
});
|
968
|
+
```
|
969
|
+
|
970
|
+
---------------------------------------
|
971
|
+
|
972
|
+
<a name="threadColors"></a>
|
973
|
+
### api.threadColors
|
974
|
+
|
975
|
+
A dictionary mapping names of all currently valid thread themes to their theme ID that are accepted by [`api.changeThreadColor`](#changeThreadColor). These themes, listed below, are the ones present in the palette UI used for selecting thread themes on the Messenger client.
|
976
|
+
|
977
|
+
- DefaultBlue: `196241301102133`
|
978
|
+
- HotPink: `169463077092846`
|
979
|
+
- AquaBlue: `2442142322678320`
|
980
|
+
- BrightPurple: `234137870477637`
|
981
|
+
- CoralPink: `980963458735625`
|
982
|
+
- Orange: `175615189761153`
|
983
|
+
- Green: `2136751179887052`
|
984
|
+
- LavenderPurple: `2058653964378557`
|
985
|
+
- Red: `2129984390566328`
|
986
|
+
- Yellow: `174636906462322`
|
987
|
+
- TealBlue: `1928399724138152`
|
988
|
+
- Aqua: `417639218648241`
|
989
|
+
- Mango: `930060997172551`
|
990
|
+
- Berry: `164535220883264`
|
991
|
+
- Citrus: `370940413392601`
|
992
|
+
- Candy: `205488546921017`
|
993
|
+
- ~~StarWars: `809305022860427`~~ (Facebook removed it.)
|
994
|
+
|
995
|
+
---------------------------------------
|
996
|
+
|
997
|
+
<a name="handleMessageRequest"></a>
|
998
|
+
### api.handleMessageRequest(threadID, accept[, callback])
|
999
|
+
|
1000
|
+
Accept or ignore message request(s) with thread id `threadID`.
|
1001
|
+
|
1002
|
+
__Arguments__
|
1003
|
+
|
1004
|
+
* `threadID`: A threadID or array of threadIDs corresponding to the target thread(s). Can be numbers or strings.
|
1005
|
+
* `accept`: Boolean indicating the new status to assign to the message request(s); true for inbox, false to others.
|
1006
|
+
* `callback(err)`: A callback called when the query is done (with an error or with null).
|
1007
|
+
|
1008
|
+
---------------------------------------
|
1009
|
+
|
1010
|
+
<a name="listen"></a>
|
1011
|
+
### api.listen([callback])
|
1012
|
+
<a name="listenMqtt"></a>
|
1013
|
+
### api.listenMqtt([callback])
|
1014
|
+
|
1015
|
+
Will call `callback` when a new message is received on this account.
|
1016
|
+
By default this won't receive events (joining/leaving a chat, title change etc...) but it can be activated with `api.setOptions({listenEvents: true})`. This will by default ignore messages sent by the current account, you can enable listening to your own messages with `api.setOptions({selfListen: true})`. This returns an `EventEmitter` that contains function `stopListening` that will stop the `listen` loop and is guaranteed to prevent any future calls to the callback given to `listen`. An immediate call to `stopListening` when an error occurs will prevent the listen function to continue.
|
1017
|
+
|
1018
|
+
If `callback` is not defined, or isn't a `Function`, you can listen to messages with event `message` and `error` from `EventEmitter` returned by this function.
|
1019
|
+
|
1020
|
+
__Arguments__
|
1021
|
+
|
1022
|
+
- `callback(error, message)`: A callback called every time the logged-in account receives a new message.
|
1023
|
+
|
1024
|
+
<a name="message"></a>
|
1025
|
+
__Message__
|
1026
|
+
|
1027
|
+
The message object will contain different fields based on its type (as determined by its `type` field). By default, the only type that will be listened for is `message`. If enabled through [setOptions](#setOptions), the message object may alternatively represent an event e.g. a read receipt. The available event types are as follows:
|
1028
|
+
|
1029
|
+
<table>
|
1030
|
+
<tr>
|
1031
|
+
<th>Event Type</th>
|
1032
|
+
<th>Field</th>
|
1033
|
+
<th>Description</th>
|
1034
|
+
</tr>
|
1035
|
+
<tr>
|
1036
|
+
<td rowspan="10">
|
1037
|
+
<code>"message"</code><br />
|
1038
|
+
A message was sent to a thread.
|
1039
|
+
</td>
|
1040
|
+
<td><code>attachments</code></td>
|
1041
|
+
<td>An array of attachments to the message. Attachments vary in type, see the attachments table below.</td>
|
1042
|
+
</tr>
|
1043
|
+
<tr>
|
1044
|
+
<td><code>body</code></td>
|
1045
|
+
<td>The string corresponding to the message that was just received.</td>
|
1046
|
+
</tr>
|
1047
|
+
<tr>
|
1048
|
+
<td><code>isGroup</code></td>
|
1049
|
+
<td>boolean, true if this thread is a group thread (more than 2 participants).</td>
|
1050
|
+
</tr>
|
1051
|
+
<tr>
|
1052
|
+
<td><code>mentions</code></td>
|
1053
|
+
<td>An object containing people mentioned/tagged in the message in the format { id: name }</td>
|
1054
|
+
</tr>
|
1055
|
+
<tr>
|
1056
|
+
<td><code>messageID</code></td>
|
1057
|
+
<td>A string representing the message ID.</td>
|
1058
|
+
</tr>
|
1059
|
+
<tr>
|
1060
|
+
<td><code>senderID</code></td>
|
1061
|
+
<td>The id of the person who sent the message in the chat with threadID.</td>
|
1062
|
+
</tr>
|
1063
|
+
<tr>
|
1064
|
+
<td><code>threadID</code></td>
|
1065
|
+
<td>The threadID representing the thread in which the message was sent.</td>
|
1066
|
+
</tr>
|
1067
|
+
<tr>
|
1068
|
+
<td><code>isUnread</code></td>
|
1069
|
+
<td>Boolean representing whether or not the message was read.</td>
|
1070
|
+
</tr>
|
1071
|
+
<tr>
|
1072
|
+
<td><code>participantIDs</code></td>
|
1073
|
+
<td>An array containing participant IDs.</td>
|
1074
|
+
</tr>
|
1075
|
+
<tr>
|
1076
|
+
<td><code>type</code></td>
|
1077
|
+
<td>For this event type, this will always be the string <code>"message"</code>.</td>
|
1078
|
+
</tr>
|
1079
|
+
<tr>
|
1080
|
+
<td rowspan="7">
|
1081
|
+
<code>"event"</code><br />
|
1082
|
+
An event occurred within a thread. Note that receiving this event type needs to be enabled with `api.setOptions({ listenEvents: true })`
|
1083
|
+
</td>
|
1084
|
+
<td><code>author</code></td>
|
1085
|
+
<td>The person who performed the event.</td>
|
1086
|
+
</tr>
|
1087
|
+
<tr>
|
1088
|
+
<td><code>logMessageBody</code></td>
|
1089
|
+
<td>String printed in the chat.</td>
|
1090
|
+
</tr>
|
1091
|
+
<tr>
|
1092
|
+
<td><code>logMessageData</code></td>
|
1093
|
+
<td>Data relevant to the event.</td>
|
1094
|
+
</tr>
|
1095
|
+
<tr>
|
1096
|
+
<td><code>logMessageType</code></td>
|
1097
|
+
<td>String representing the type of event (<code>log:subscribe</code>, <code>log:unsubscribe</code>, <code>log:thread-name</code>, <code>log:thread-color</code>, <code>log:thread-icon</code>, <code>log:user-nickname</code>, <code>log:thread-call</code>, <code>log:thread-admins</code>)</td>
|
1098
|
+
</tr>
|
1099
|
+
<tr>
|
1100
|
+
<td><code>threadID</code></td>
|
1101
|
+
<td>The threadID representing the thread in which the message was sent.</td>
|
1102
|
+
</tr>
|
1103
|
+
<tr>
|
1104
|
+
<td><code>participantIDs</code></td>
|
1105
|
+
<td>An array containing participant IDs.</td>
|
1106
|
+
</tr>
|
1107
|
+
<tr>
|
1108
|
+
<td><code>type</code></td>
|
1109
|
+
<td>For this event type, this will always be the string <code>"event"</code>.</td>
|
1110
|
+
</tr>
|
1111
|
+
<tr>
|
1112
|
+
<td rowspan="5">
|
1113
|
+
<code>"typ"</code><br />
|
1114
|
+
A user in a thread is typing. Note that receiving this event type needs to be enabled with `api.setOptions({ listenTyping: true })`
|
1115
|
+
</td>
|
1116
|
+
<td><code>from</code></td>
|
1117
|
+
<td>ID of the user who started/stopped typing.</td>
|
1118
|
+
</tr>
|
1119
|
+
<tr>
|
1120
|
+
<td><code>fromMobile</code></td>
|
1121
|
+
<td>Boolean representing whether or not the person's using a mobile device to type.</td>
|
1122
|
+
</tr>
|
1123
|
+
<tr>
|
1124
|
+
<td><code>isTyping</code></td>
|
1125
|
+
<td>Boolean representing whether or not a person started typing.</td>
|
1126
|
+
</tr>
|
1127
|
+
<tr>
|
1128
|
+
<td><code>threadID</code></td>
|
1129
|
+
<td>The threadID representing the thread in which a user is typing.</td>
|
1130
|
+
</tr>
|
1131
|
+
<tr>
|
1132
|
+
<td><code>type</code></td>
|
1133
|
+
<td>For this event type, this will always be the string <code>"typ"</code>.</td>
|
1134
|
+
</tr>
|
1135
|
+
<tr>
|
1136
|
+
<td rowspan="3">
|
1137
|
+
<code>"read"</code><br />
|
1138
|
+
The current API user has read a message.
|
1139
|
+
</td>
|
1140
|
+
<td><code>threadID</code></td>
|
1141
|
+
<td>The threadID representing the thread in which the message was sent.</td>
|
1142
|
+
</tr>
|
1143
|
+
<tr>
|
1144
|
+
<td><code>time</code></td>
|
1145
|
+
<td>The time at which the user read the message.</td>
|
1146
|
+
</tr>
|
1147
|
+
<tr>
|
1148
|
+
<td><code>type</code></td>
|
1149
|
+
<td>For this event type, this will always be the string <code>"read"</code>.</td>
|
1150
|
+
</tr>
|
1151
|
+
<tr>
|
1152
|
+
<td rowspan="4">
|
1153
|
+
<code>"read_receipt"</code><br />
|
1154
|
+
A user within a thread has seen a message sent by the API user.
|
1155
|
+
</td>
|
1156
|
+
<td><code>reader</code></td>
|
1157
|
+
<td>ID of the user who just read the message.</td>
|
1158
|
+
</tr>
|
1159
|
+
<tr>
|
1160
|
+
<td><code>threadID</code></td>
|
1161
|
+
<td>The thread in which the message was read.</td>
|
1162
|
+
</tr>
|
1163
|
+
<tr>
|
1164
|
+
<td><code>time</code></td>
|
1165
|
+
<td>The time at which the reader read the message.</td>
|
1166
|
+
</tr>
|
1167
|
+
<tr>
|
1168
|
+
<td><code>type</code></td>
|
1169
|
+
<td>For this event type, this will always be the string <code>"read_receipt"</code>.</td>
|
1170
|
+
</tr>
|
1171
|
+
<tr>
|
1172
|
+
<td rowspan="8">
|
1173
|
+
<code>"message_reaction"</code><br />
|
1174
|
+
A user has sent a reaction to a message.
|
1175
|
+
</td>
|
1176
|
+
<td><code>messageID</code></td>
|
1177
|
+
<td>The ID of the message</td>
|
1178
|
+
</tr>
|
1179
|
+
<tr>
|
1180
|
+
<td><code>offlineThreadingID</code></td>
|
1181
|
+
<td>The offline message ID</td>
|
1182
|
+
</tr>
|
1183
|
+
<tr>
|
1184
|
+
<td><code>reaction</code></td>
|
1185
|
+
<td>Contains reaction emoji</td>
|
1186
|
+
</tr>
|
1187
|
+
<tr>
|
1188
|
+
<td><code>senderID</code></td>
|
1189
|
+
<td>ID of the author the message, where has been reaction added</td>
|
1190
|
+
</tr>
|
1191
|
+
<tr>
|
1192
|
+
<td><code>threadID</code></td>
|
1193
|
+
<td>ID of the thread where the message has been sent</td>
|
1194
|
+
</tr>
|
1195
|
+
<tr>
|
1196
|
+
<td><code>timestamp</code></td>
|
1197
|
+
<td>Unix Timestamp (in miliseconds) when the reaction was sent</td>
|
1198
|
+
</tr>
|
1199
|
+
<tr>
|
1200
|
+
<td><code>type</code></td>
|
1201
|
+
<td>For this event type, this will always be the string <code>"message_reaction"</code>.</td>
|
1202
|
+
</tr>
|
1203
|
+
<tr>
|
1204
|
+
<td><code>userID</code></td>
|
1205
|
+
<td>ID of the reaction sender</td>
|
1206
|
+
</tr>
|
1207
|
+
<tr>
|
1208
|
+
<td rowspan="4"><a name="presence"></a>
|
1209
|
+
<code>"presence"</code><br />
|
1210
|
+
The online status of the user's friends. Note that receiving this event type needs to be enabled with <code>api.setOptions({ updatePresence: true })</code>
|
1211
|
+
</td>
|
1212
|
+
<td><code>statuses</code></td>
|
1213
|
+
<td>The online status of the user. <code>0</code> means the user is idle (away for 2 minutes) and <code>2</code> means the user is online (we don't know what 1 or above 2 means...).</td>
|
1214
|
+
</tr>
|
1215
|
+
<tr>
|
1216
|
+
<td><code>timestamp</code></td>
|
1217
|
+
<td>The time when the user was last online.</td>
|
1218
|
+
</tr>
|
1219
|
+
<tr>
|
1220
|
+
<td><code>type</code></td>
|
1221
|
+
<td>For this event type, this will always be the string <code>"presence"</code>.</td>
|
1222
|
+
</tr>
|
1223
|
+
<tr>
|
1224
|
+
<td><code>userID</code></td>
|
1225
|
+
<td>The ID of the user whose status this packet is describing.</td>
|
1226
|
+
</tr>
|
1227
|
+
<tr>
|
1228
|
+
<td rowspan="5">
|
1229
|
+
<code>"message_unsend"</code><br />
|
1230
|
+
A revoke message request for a message from a thread was received.
|
1231
|
+
</td>
|
1232
|
+
<td><code>threadID</code></td>
|
1233
|
+
<td>The threadID representing the thread in which the revoke message request was received.</td>
|
1234
|
+
</tr>
|
1235
|
+
<tr>
|
1236
|
+
<td><code>senderID</code></td>
|
1237
|
+
<td>The id of the person who request to revoke message on threadID.</td>
|
1238
|
+
</tr>
|
1239
|
+
<tr>
|
1240
|
+
<td><code>messageID</code></td>
|
1241
|
+
<td>A string representing the message ID that the person request to revoke message want to.</td>
|
1242
|
+
</tr>
|
1243
|
+
<tr>
|
1244
|
+
<td><code>deletionTimestamp</code></td>
|
1245
|
+
<td>The time when the request was sent.</td>
|
1246
|
+
</tr>
|
1247
|
+
<tr>
|
1248
|
+
<td><code>type</code></td>
|
1249
|
+
<td>For this event type, this will always be the string <code>"message_unsend"</code>.</td>
|
1250
|
+
</tr>
|
1251
|
+
<tr>
|
1252
|
+
<td rowspan="11">
|
1253
|
+
<code>"message_reply"</code><br />
|
1254
|
+
A reply message was sent to a thread.
|
1255
|
+
</td>
|
1256
|
+
<td><code>attachments</code></td>
|
1257
|
+
<td>An array of attachments to the message. Attachments vary in type, see the attachments table below.</td>
|
1258
|
+
</tr>
|
1259
|
+
<tr>
|
1260
|
+
<td><code>body</code></td>
|
1261
|
+
<td>The string corresponding to the message that was just received.</td>
|
1262
|
+
</tr>
|
1263
|
+
<tr>
|
1264
|
+
<td><code>isGroup</code></td>
|
1265
|
+
<td>boolean, true if this thread is a group thread (more than 2 participants).</td>
|
1266
|
+
</tr>
|
1267
|
+
<tr>
|
1268
|
+
<td><code>mentions</code></td>
|
1269
|
+
<td>An object containing people mentioned/tagged in the message in the format { id: name }</td>
|
1270
|
+
</tr>
|
1271
|
+
<tr>
|
1272
|
+
<td><code>messageID</code></td>
|
1273
|
+
<td>A string representing the message ID.</td>
|
1274
|
+
</tr>
|
1275
|
+
<tr>
|
1276
|
+
<td><code>senderID</code></td>
|
1277
|
+
<td>The id of the person who sent the message in the chat with threadID.</td>
|
1278
|
+
</tr>
|
1279
|
+
<tr>
|
1280
|
+
<td><code>threadID</code></td>
|
1281
|
+
<td>The threadID representing the thread in which the message was sent.</td>
|
1282
|
+
</tr>
|
1283
|
+
<tr>
|
1284
|
+
<td><code>isUnread</code></td>
|
1285
|
+
<td>Boolean representing whether or not the message was read.</td>
|
1286
|
+
</tr>
|
1287
|
+
<tr>
|
1288
|
+
<td><code>type</code></td>
|
1289
|
+
<td>For this event type, this will always be the string <code>"message_reply"</code>.</td>
|
1290
|
+
</tr>
|
1291
|
+
<tr>
|
1292
|
+
<td><code>participantIDs</code></td>
|
1293
|
+
<td>An array containing participant IDs.</td>
|
1294
|
+
</tr>
|
1295
|
+
<tr>
|
1296
|
+
<td><code>messageReply</code></td>
|
1297
|
+
<td>An object represent a message being replied. Content inside is the same like a normal <code>"message"</code> event.</td>
|
1298
|
+
</tr>
|
1299
|
+
</table>
|
1300
|
+
|
1301
|
+
__Attachments__
|
1302
|
+
|
1303
|
+
Similar to how messages can vary based on their `type`, so too can the `attachments` within `"message"` events. Each attachment will consist of an object of one of the following types:
|
1304
|
+
|
1305
|
+
| Attachment Type | Fields |
|
1306
|
+
| --------------- | ------ |
|
1307
|
+
| `"sticker"` | `ID`, `url`, `packID`, `spriteUrl`, `spriteUrl2x`, `width`, `height`, `caption`, `description`, `frameCount`, `frameRate`, `framesPerRow`, `framesPerCol` |
|
1308
|
+
| `"file"` | `ID`, `filename`, `url`, `isMalicious`, `contentType` |
|
1309
|
+
| `"photo"` | `ID`, `filename`, `thumbnailUrl`, `previewUrl`, `previewWidth`, `previewHeight`, `largePreviewUrl`, `largePreviewWidth`, `largePreviewHeight` |
|
1310
|
+
| `"animated_image"` | `ID`, `filename`, `previewUrl`, `previewWidth`, `previewHeight`, `url`, `width`, `height` |
|
1311
|
+
| `"video"` | `ID`, `filename`, `previewUrl`, `previewWidth`, `previewHeight`, `url`, `width`, `height`, `duration`, `videoType` |
|
1312
|
+
| `"audio"` | `ID`, `filename`, `audioType`, `duration`, `url`, `isVoiceMail` |
|
1313
|
+
| `"location"` | `ID`, `latitude`, `longitude`, `image`, `width`, `height`, `url`, `address` |
|
1314
|
+
| `"share"` | `ID`, `url`, `title`, `description`, `source`, `image`, `width`, `height`, `playable`, `duration`, `playableUrl`, `subattachments`, `properties` |
|
1315
|
+
|
1316
|
+
__Example__
|
1317
|
+
|
1318
|
+
```js
|
1319
|
+
const fs = require("fs");
|
1320
|
+
const login = require("fca-unofficial");
|
1321
|
+
|
1322
|
+
// Simple echo bot. He'll repeat anything that you say.
|
1323
|
+
// Will stop when you say '/stop'
|
1324
|
+
|
1325
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
1326
|
+
if(err) return console.error(err);
|
1327
|
+
|
1328
|
+
api.setOptions({listenEvents: true});
|
1329
|
+
|
1330
|
+
var listenEmitter = api.listen((err, event) => {
|
1331
|
+
if(err) return console.error(err);
|
1332
|
+
|
1333
|
+
switch (event.type) {
|
1334
|
+
case "message":
|
1335
|
+
if(event.body === '/stop') {
|
1336
|
+
api.sendMessage("Goodbye...", event.threadID);
|
1337
|
+
return listenEmitter.stopListening();
|
1338
|
+
}
|
1339
|
+
api.markAsRead(event.threadID, (err) => {
|
1340
|
+
if(err) console.log(err);
|
1341
|
+
});
|
1342
|
+
api.sendMessage("TEST BOT: " + event.body, event.threadID);
|
1343
|
+
break;
|
1344
|
+
case "event":
|
1345
|
+
console.log(event);
|
1346
|
+
break;
|
1347
|
+
}
|
1348
|
+
});
|
1349
|
+
});
|
1350
|
+
```
|
1351
|
+
|
1352
|
+
---------------------------------------
|
1353
|
+
|
1354
|
+
<a name="logout"></a>
|
1355
|
+
### api.logout([callback])
|
1356
|
+
|
1357
|
+
Logs out the current user.
|
1358
|
+
|
1359
|
+
__Arguments__
|
1360
|
+
|
1361
|
+
* `callback(err)`: A callback called when the query is done (either with an error or with null).
|
1362
|
+
|
1363
|
+
---------------------------------------
|
1364
|
+
|
1365
|
+
<a name="markAsDelivered"></a>
|
1366
|
+
### api.markAsDelivered(threadID, messageID[, callback]])
|
1367
|
+
|
1368
|
+
Given a threadID and a messageID will mark that message as delivered. If a message is marked as delivered that tells facebook servers that it was recieved.
|
1369
|
+
|
1370
|
+
You can also mark new messages as delivered automatically. This is enabled by default. See [api.setOptions](#setOptions).
|
1371
|
+
|
1372
|
+
__Arguments__
|
1373
|
+
|
1374
|
+
* `threadID` - The id of the thread in which you want to mark the message as delivered.
|
1375
|
+
* `messageID` - The id of the message want to mark as delivered.
|
1376
|
+
* `callback(err)` - A callback called when the operation is done maybe with an object representing an error.
|
1377
|
+
|
1378
|
+
__Example__
|
1379
|
+
|
1380
|
+
```js
|
1381
|
+
const fs = require("fs");
|
1382
|
+
const login = require("facebook-chat-api");
|
1383
|
+
|
1384
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
1385
|
+
if(err) return console.error(err);
|
1386
|
+
|
1387
|
+
api.listen((err, message) => {
|
1388
|
+
if(err) return console.error(err);
|
1389
|
+
|
1390
|
+
// Marks messages as delivered immediately after they're received
|
1391
|
+
api.markAsDelivered(message.threadID, message.messageID);
|
1392
|
+
});
|
1393
|
+
});
|
1394
|
+
```
|
1395
|
+
|
1396
|
+
---------------------------------------
|
1397
|
+
|
1398
|
+
<a name="markAsRead"></a>
|
1399
|
+
### api.markAsRead(threadID, [read[, callback]])
|
1400
|
+
|
1401
|
+
Given a threadID will mark all the unread messages in a thread as read. Facebook will take a couple of seconds to show that you've read the messages.
|
1402
|
+
|
1403
|
+
You can also mark new messages as read automatically. See [api.setOptions](#setOptions). But be careful, this will make your account getting banned, especially when receiving *HUGE* amount of messages.
|
1404
|
+
|
1405
|
+
__Arguments__
|
1406
|
+
|
1407
|
+
* `threadID` - The id of the thread in which you want to mark the messages as read.
|
1408
|
+
* `read` - An optional boolean where `true` means to mark the message as being "read" and `false` means to mark the message as being "unread".
|
1409
|
+
* `callback(err)` - A callback called when the operation is done maybe with an object representing an error.
|
1410
|
+
|
1411
|
+
__Example__
|
1412
|
+
|
1413
|
+
```js
|
1414
|
+
const fs = require("fs");
|
1415
|
+
const login = require("fca-unofficial");
|
1416
|
+
|
1417
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
1418
|
+
if(err) return console.error(err);
|
1419
|
+
|
1420
|
+
api.listen((err, message) => {
|
1421
|
+
if(err) return console.error(err);
|
1422
|
+
|
1423
|
+
// Marks messages as read immediately after they're received
|
1424
|
+
api.markAsRead(message.threadID);
|
1425
|
+
});
|
1426
|
+
});
|
1427
|
+
```
|
1428
|
+
|
1429
|
+
---------------------------------------
|
1430
|
+
|
1431
|
+
<a name="markAsReadAll"></a>
|
1432
|
+
### api.markAsReadAll([callback])
|
1433
|
+
|
1434
|
+
This function will mark all of messages in your inbox readed.
|
1435
|
+
|
1436
|
+
---------------------------------------
|
1437
|
+
|
1438
|
+
<a name="markAsSeen"></a>
|
1439
|
+
### api.markAsSeen([seenTimestamp][, callback])
|
1440
|
+
|
1441
|
+
This function will mark your entire inbox as seen (don't be confused with read!).
|
1442
|
+
|
1443
|
+
---------------------------------------
|
1444
|
+
|
1445
|
+
<a name="muteThread"></a>
|
1446
|
+
### api.muteThread(threadID, muteSeconds[, callback])
|
1447
|
+
|
1448
|
+
Mute a chat for a period of time, or unmute a chat.
|
1449
|
+
|
1450
|
+
__Arguments__
|
1451
|
+
|
1452
|
+
* `threadID` - The ID of the chat you want to mute.
|
1453
|
+
* `muteSeconds` - Mute the chat for this amount of seconds. Use `0` to unmute a chat. Use '-1' to mute a chat indefinitely.
|
1454
|
+
* `callback(err)` - A callback called when the operation is done maybe with an object representing an error.
|
1455
|
+
|
1456
|
+
__Example__
|
1457
|
+
|
1458
|
+
```js
|
1459
|
+
const fs = require("fs");
|
1460
|
+
const login = require("fca-unofficial");
|
1461
|
+
|
1462
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
1463
|
+
if(err) return console.error(err);
|
1464
|
+
|
1465
|
+
api.listen((err, message) => {
|
1466
|
+
if(err) return console.error(err);
|
1467
|
+
|
1468
|
+
// Mute all incoming chats for one minute
|
1469
|
+
api.muteThread(message.threadID, 60);
|
1470
|
+
});
|
1471
|
+
});
|
1472
|
+
```
|
1473
|
+
|
1474
|
+
---------------------------------------
|
1475
|
+
|
1476
|
+
<a name="removeUserFromGroup"></a>
|
1477
|
+
### api.removeUserFromGroup(userID, threadID[, callback])
|
1478
|
+
|
1479
|
+
Removes a user from a group chat.
|
1480
|
+
|
1481
|
+
__Arguments__
|
1482
|
+
|
1483
|
+
* `userID`: User ID.
|
1484
|
+
* `threadID`: Group chat ID.
|
1485
|
+
* `callback(err)`: A callback called when the query is done (either with an error or with no arguments).
|
1486
|
+
|
1487
|
+
---------------------------------------
|
1488
|
+
|
1489
|
+
<a name="resolvePhotoUrl"></a>
|
1490
|
+
### api.resolvePhotoUrl(photoID, callback)
|
1491
|
+
|
1492
|
+
Resolves the URL to the full-size photo, given its ID. This function is useful for retrieving the full-size photo URL
|
1493
|
+
of image attachments in messages, returned by [`api.getThreadHistory`](#getThreadHistory).
|
1494
|
+
|
1495
|
+
__Arguments__
|
1496
|
+
|
1497
|
+
* `photoID`: Photo ID.
|
1498
|
+
* `callback(err, url)`: A callback called when the query is done (either with an error or with the photo's URL). `url` is a string with the photo's URL.
|
1499
|
+
|
1500
|
+
---------------------------------------
|
1501
|
+
|
1502
|
+
<a name="searchForThread"></a>
|
1503
|
+
### api.searchForThread(name, callback)
|
1504
|
+
|
1505
|
+
> This part is outdated.
|
1506
|
+
> see #396
|
1507
|
+
|
1508
|
+
Takes a chat title (thread name) and returns matching results as a formatted threads array (ordered according to Facebook).
|
1509
|
+
|
1510
|
+
__Arguments__
|
1511
|
+
* `name`: A messageID string or messageID string array
|
1512
|
+
* `callback(err, obj)`: A callback called when the query is done (either with an error or a thread object). The object passed in the callback has the following shape: `threadID`, <del>`participants`</del>, `participantIDs`, `formerParticipants`, `name`, `nicknames`, `snippet`, `snippetHasAttachment`, `snippetAttachments`, `snippetSender`, `unreadCount`, `messageCount`, `imageSrc`, `timestamp`, `serverTimestamp`, `muteSettings`, `isCanonicalUser`, `isCanonical`, `canonicalFbid`, `isSubscribed`, `rootMessageThreadingID`, `folder`, `isArchived`, `recipientsLoadable`, `hasEmailParticipant`, `readOnly`, `canReply`, `composerEnabled`, `blockedParticipants`, `lastMessageID`
|
1513
|
+
|
1514
|
+
---------------------------------------
|
1515
|
+
|
1516
|
+
<a name="sendMessage"></a>
|
1517
|
+
### api.sendMessage(message, threadID[, callback][, messageID])
|
1518
|
+
|
1519
|
+
Sends the given message to the threadID.
|
1520
|
+
|
1521
|
+
__Arguments__
|
1522
|
+
|
1523
|
+
* `message`: A string (for backward compatibility) or a message object as described below.
|
1524
|
+
* `threadID`: A string, number, or array representing a thread. It happens to be someone's userID in the case of a one to one conversation or an array of userIDs when starting a new group chat.
|
1525
|
+
* `callback(err, messageInfo)`: (Optional) A callback called when sending the message is done (either with an error or with an confirmation object). `messageInfo` contains the `threadID` where the message was sent and a `messageID`, as well as the `timestamp` of the message.
|
1526
|
+
* `messageID`: (Optional) A string representing a message you want to reply.
|
1527
|
+
|
1528
|
+
__Message Object__:
|
1529
|
+
|
1530
|
+
Various types of message can be sent:
|
1531
|
+
* *Regular:* set field `body` to the desired message as a string.
|
1532
|
+
* *Sticker:* set a field `sticker` to the desired sticker ID.
|
1533
|
+
* *File or image:* Set field `attachment` to a readable stream or an array of readable streams.
|
1534
|
+
* *URL:* set a field `url` to the desired URL.
|
1535
|
+
* *Emoji:* set field `emoji` to the desired emoji as a string and set field `emojiSize` with size of the emoji (`small`, `medium`, `large`)
|
1536
|
+
* *Mentions:* set field `mentions` to an array of objects. Objects should have the `tag` field set to the text that should be highlighted in the mention. The object should have an `id` field, where the `id` is the user id of the person being mentioned. The instance of `tag` that is highlighted is determined through indexOf, an optional `fromIndex`
|
1537
|
+
can be passed in to specify the start index to start searching for the `tag` text
|
1538
|
+
in `body` (default=0). (See below for an example.)
|
1539
|
+
* *Location:* set field `location` to an object with `latitude` and `longitude` fields. Optionally set field `current` of the `location` object to true to indicate the location is the user’s current location. Otherwise the location will be sent as a pinned location.
|
1540
|
+
|
1541
|
+
Note that a message can only be a regular message (which can be empty) and optionally one of the following: a sticker, an attachment or a url.
|
1542
|
+
|
1543
|
+
__Tip__: to find your own ID, you can look inside the cookies. The `userID` is under the name `c_user`.
|
1544
|
+
|
1545
|
+
__Example (Basic Message)__
|
1546
|
+
```js
|
1547
|
+
const fs = require("fs");
|
1548
|
+
const login = require("fca-unofficial");
|
1549
|
+
|
1550
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
1551
|
+
if(err) return console.error(err);
|
1552
|
+
|
1553
|
+
var yourID = "000000000000000";
|
1554
|
+
var msg = {body: "Hey!"};
|
1555
|
+
api.sendMessage(msg, yourID);
|
1556
|
+
});
|
1557
|
+
```
|
1558
|
+
|
1559
|
+
__Example (File upload)__
|
1560
|
+
```js
|
1561
|
+
const fs = require("fs");
|
1562
|
+
const login = require("fca-unofficial");
|
1563
|
+
|
1564
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
1565
|
+
if(err) return console.error(err);
|
1566
|
+
|
1567
|
+
// This example uploads an image called image.jpg
|
1568
|
+
var yourID = "000000000000000";
|
1569
|
+
var msg = {
|
1570
|
+
body: "Hey!",
|
1571
|
+
attachment: fs.createReadStream(__dirname + '/image.jpg')
|
1572
|
+
}
|
1573
|
+
api.sendMessage(msg, yourID);
|
1574
|
+
});
|
1575
|
+
```
|
1576
|
+
|
1577
|
+
__Example (Mention)__
|
1578
|
+
```js
|
1579
|
+
const login = require("fca-unofficial");
|
1580
|
+
|
1581
|
+
login({email: "EMAIL", password: "PASSWORD"}, (err, api) => {
|
1582
|
+
if(err) return console.error(err);
|
1583
|
+
|
1584
|
+
api.listen((err, message) => {
|
1585
|
+
if (message && message.body) {
|
1586
|
+
// Getting the actual sender name from ID involves calling
|
1587
|
+
// `api.getThreadInfo` and `api.getUserInfo`
|
1588
|
+
api.sendMessage({
|
1589
|
+
body: 'Hello @Sender! @Sender!',
|
1590
|
+
mentions: [{
|
1591
|
+
tag: '@Sender',
|
1592
|
+
id: message.senderID,
|
1593
|
+
fromIndex: 9, // Highlight the second occurrence of @Sender
|
1594
|
+
}],
|
1595
|
+
}, message.threadID);
|
1596
|
+
}
|
1597
|
+
});
|
1598
|
+
});
|
1599
|
+
```
|
1600
|
+
|
1601
|
+
__Example (Location)__
|
1602
|
+
```js
|
1603
|
+
const login = require("fca-unofficial");
|
1604
|
+
login({email: "EMAIL", password: "PASSWORD"}, (err, api) => {
|
1605
|
+
if(err) return console.error(err);
|
1606
|
+
var yourID = "000000000000000";
|
1607
|
+
const msg = {
|
1608
|
+
location: { latitude: 48.858093, longitude: 2.294694, current: true },
|
1609
|
+
};
|
1610
|
+
api.sendMessage(msg, yourID);
|
1611
|
+
});
|
1612
|
+
```
|
1613
|
+
|
1614
|
+
---------------------------------------
|
1615
|
+
|
1616
|
+
<a name="sendTypingIndicator"></a>
|
1617
|
+
### api.sendTypingIndicator(threadID[, callback])
|
1618
|
+
|
1619
|
+
Sends a "USERNAME is typing" indicator to other members of the thread indicated by `threadID`. This indication will disappear after 30 second or when the `end` function is called. The `end` function is returned by `api.sendTypingIndicator`.
|
1620
|
+
|
1621
|
+
__Arguments__
|
1622
|
+
|
1623
|
+
* `threadID`: Group chat ID.
|
1624
|
+
* `callback(err)`: A callback called when the query is done (with an error or with null).
|
1625
|
+
|
1626
|
+
---------------------------------------
|
1627
|
+
|
1628
|
+
<a name="setMessageReaction"></a>
|
1629
|
+
### api.setMessageReaction(reaction, messageID[, callback[, forceCustomReaction]])
|
1630
|
+
|
1631
|
+
Sets reaction on message
|
1632
|
+
|
1633
|
+
__Arguments__
|
1634
|
+
|
1635
|
+
* `reaction`: A string containing either an emoji, an emoji in unicode, or an emoji shortcut (see list of supported emojis below). The string can be left empty ("") in order to remove a reaction.
|
1636
|
+
* `messageID`: A string representing the message ID.
|
1637
|
+
* `callback(err)`: A callback called when sending the reaction is done.
|
1638
|
+
* `forceCustomReaction`: Forcing the use of an emoji for setting reaction **(WARNING: NOT TESTED, YOU SHOULD NOT USE THIS AT ALL, UNLESS YOU'RE TESTING A NEW EMOJI)**
|
1639
|
+
|
1640
|
+
__Supported Emojis__
|
1641
|
+
|
1642
|
+
|Emoji|Text|Unicode|Shortcuts|
|
1643
|
+
|---|---|---|---|
|
1644
|
+
|😍|`😍`|`\uD83D\uDE0D`|`:love:`, `:heart_eyes:`|
|
1645
|
+
|😆|`😆`|`\uD83D\uDE06`|`:haha:`, `:laughing:`|
|
1646
|
+
|😮|`😮`|`\uD83D\uDE2E`|`:wow:`, `:open_mouth:`|
|
1647
|
+
|😢|`😢`|`\uD83D\uDE22`|`:sad:`, `:cry:`|
|
1648
|
+
|😠|`😠`|`\uD83D\uDE20`|`:angry:`|
|
1649
|
+
|👍|`👍`|`\uD83D\uDC4D`|`:like:`, `:thumbsup:`|
|
1650
|
+
|👎|`👎`|`\uD83D\uDC4E`|`:dislike:`, `:thumbsdown:`|
|
1651
|
+
|❤|`❤`|`\u2764`|`:heart:`|
|
1652
|
+
|💗|`💗`|`\uD83D\uDC97`|`:glowingheart:`|
|
1653
|
+
|
1654
|
+
---------------------------------------
|
1655
|
+
|
1656
|
+
<a name="setOptions"></a>
|
1657
|
+
### api.setOptions(options)
|
1658
|
+
|
1659
|
+
Sets various configurable options for the api.
|
1660
|
+
|
1661
|
+
__Arguments__
|
1662
|
+
|
1663
|
+
* `options` - An object containing the new values for the options that you want
|
1664
|
+
to set. If the value for an option is unspecified, it is unchanged. The following options are possible.
|
1665
|
+
- `pauseLog`: (Default `false`) Set this to `true` if you want to pause the npmlog output.
|
1666
|
+
- `logLevel`: The desired logging level as determined by npmlog. Choose
|
1667
|
+
from either `"silly"`, `"verbose"`, `"info"`, `"http"`, `"warn"`, `"error"`, or `"silent"`.
|
1668
|
+
- `selfListen`: (Default `false`) Set this to `true` if you want your api
|
1669
|
+
to receive messages from its own account. This is to be used with
|
1670
|
+
caution, as it can result in loops (a simple echo bot will send messages
|
1671
|
+
forever).
|
1672
|
+
- `listenEvents`: (Default `false`) Will make [api.listen](#listen) also handle events (look at api.listen for more details).
|
1673
|
+
- `pageID`: (Default empty) Makes [api.listen](#listen) only receive messages through the page specified by that ID. Also makes [api.sendMessage](#sendMessage) send from the page.
|
1674
|
+
- `updatePresence`: (Default `false`) Will make [api.listen](#listen) also return `presence` ([api.listen](#presence) for more details).
|
1675
|
+
- `forceLogin`: (Default `false`) Will automatically approve of any recent logins and continue with the login process.
|
1676
|
+
- `userAgent`: (Default `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/600.3.18 (KHTML, like Gecko) Version/8.0.3 Safari/600.3.18`) The desired simulated User Agent.
|
1677
|
+
- `autoMarkDelivery`: (Default `true`) Will automatically mark new messages as delivered. See [api.markAsDelivered](#markAsDelivered).
|
1678
|
+
- `autoMarkRead`: (Default `false`) Will automatically mark new messages as read/seen. See [api.markAsRead](#markAsRead).
|
1679
|
+
- `proxy`: (Default empty) Set this to proxy server address to use proxy. Note: Only HTTP Proxies which support CONNECT method is supported.
|
1680
|
+
- `online`: (Default `true`) Set account's online state.
|
1681
|
+
|
1682
|
+
__Example__
|
1683
|
+
|
1684
|
+
```js
|
1685
|
+
const fs = require("fs");
|
1686
|
+
const login = require("fca-unofficial");
|
1687
|
+
|
1688
|
+
// Simple echo bot. This will send messages forever.
|
1689
|
+
|
1690
|
+
login({appState: JSON.parse(fs.readFileSync('appstate.json', 'utf8'))}, (err, api) => {
|
1691
|
+
if(err) return console.error(err);
|
1692
|
+
|
1693
|
+
api.setOptions({
|
1694
|
+
selfListen: true,
|
1695
|
+
logLevel: "silent"
|
1696
|
+
});
|
1697
|
+
|
1698
|
+
api.listen((err, message) => {
|
1699
|
+
if(err) return console.error(err);
|
1700
|
+
|
1701
|
+
// Ignore empty messages (photos etc.)
|
1702
|
+
if (typeof message.body === "string") {
|
1703
|
+
api.sendMessage(message.body, message.threadID);
|
1704
|
+
}
|
1705
|
+
});
|
1706
|
+
});
|
1707
|
+
```
|
1708
|
+
|
1709
|
+
---------------------------------------
|
1710
|
+
|
1711
|
+
<a name="setTitle"></a>
|
1712
|
+
### api.setTitle(newTitle, threadID[, callback])
|
1713
|
+
|
1714
|
+
Sets the title of the group chat with thread id `threadID` to `newTitle`.
|
1715
|
+
|
1716
|
+
Note: This will not work if the thread id corresponds to a single-user chat or if the bot is not in the group chat.
|
1717
|
+
|
1718
|
+
__Arguments__
|
1719
|
+
|
1720
|
+
* `newTitle`: A string representing the new title.
|
1721
|
+
* `threadID`: A string or number representing a thread. It happens to be someone's userID in the case of a one to one conversation.
|
1722
|
+
* `callback(err, obj)` - A callback called when sending the message is done (either with an error or with an confirmation object). `obj` contains only the threadID where the message was sent.
|
1723
|
+
|
1724
|
+
---------------------------------------
|
1725
|
+
|
1726
|
+
<a name="unsendMessage"></a>
|
1727
|
+
### api.unsendMessage(messageID[, callback])
|
1728
|
+
|
1729
|
+
Revokes a message from anyone that could see that message with `messageID`
|
1730
|
+
|
1731
|
+
Note: This will only work if the message is sent by you and was sent less than 10 minutes ago.
|
1732
|
+
|
1733
|
+
__Arguments__
|
1734
|
+
|
1735
|
+
* `messageID`: Message ID you want to unsend.
|
1736
|
+
* `callback(err)`: A callback called when the query is done (with an error or with null).
|
1737
|
+
|
1738
|
+
---------------------------------------
|