BotCore is a framework for writing and managing multiple Facebook Messenger bots through a common layer. It supports interfacing with facebook-chat-api and fbchat.
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Logging into BotCore
3 | *
4 | * The `LoginCredentials` object is required for logging in to any application using BotCore. The
5 | * idea of it is to store your (sensitive) credentials separately from the source of your project, in a
6 | * place that won't be accidentally committed to a repo and published for the world to see. It consists
7 | * of several required keys that allow BotCore to log in to both Facebook and the MemCachier service
8 | * (used to cache logins) on your behalf. The keys are listed and explained below.
9 | *
10 | * > **NOTE**: to obtain the values for the `MEMCACHIER_` variables, you must [sign up for a free
11 | * MemCachier account](https://www.memcachier.com/users/signup) and create a cache. From there, you
12 | * will be able to retrieve the requisite info from your dashboard.
13 | *
14 | * I recommend the following two methods for storing your credentials object due to their ease of use:
15 | *
16 | * 1. *Environment variables*: you can store these keys as environment variables, which will prevent
17 | * them from being stored in any file in your project. When logging in, simply pass `process.env` as your
18 | * credentials object, because it will contain all of the required keys needed to log in successfully!
19 | * You can find an example of how to configure your credentials this way in `examples/credentials.sh`
20 | * in the BotCore repo.
21 | *
22 | * 2. *A gitignored credentials file*: you can create a file (`credentials.js` or similar) that contains
23 | * all of your required credentials keys as exported variables, and then simply import this as a JS
24 | * module wherever you need to log in. Don't forget to add this credentials file to your `.gitignore`
25 | * so that your credentials aren't exposed! You can find an example of how to configure your credentials
26 | * this way in `examples/credentials.js` in the BotCore repo.
27 | *
28 | * These are two of many possible ways you could choose to store this information. Keep in mind that
29 | * regardless of which method you choose, you will have to eventually pass a JavaScript object containing
30 | * the following keys to the {@link login} function, so you will need to be able to access this
31 | * information at runtime.
32 | *
33 | * Also keep in mind that the `FACEBOOK_EMAIL` and `FACEBOOK_PASSWORD` keys are only required for login
34 | * if you do not have an active Facebook login session stored in BotCore (i.e. you have logged in
35 | * recently, and Facebook hasn't decided to terminate your session yet). BotCore caches your recent
36 | * logins to prevent too many hard (username/password) logins, unless you use the `forceLogin` option.
37 | * If you are using several bots with BotCore, consider storing your `FACEBOOK_EMAIL` and
38 | * `FACEBOOK_PASSWORD` keys with only one of them, and only using your `MEMCACHIER_` variables to log in
39 | * from other bots.
40 | */
41 | export interface LoginCredentials {
42 | /**
43 | * Facebook account email for login (optional if already logged in once)
44 | */
45 | FACEBOOK_EMAIL?: string,
46 | /**
47 | * Facebook account password for login (optional if already logged in once)
48 | */
49 | FACEBOOK_PASSWORD?: string,
50 | /**
51 | * Memcachier servers (from [dashboard](https://www.memcachier.com/caches)
52 | * or Heroku) for storage
53 | */
54 | MEMCACHIER_SERVERS: string,
55 | /**
56 | * Memcachier username (from [dashboard](https://www.memcachier.com/caches)
57 | * or Heroku) for storage
58 | */
59 | MEMCACHIER_USERNAME: string,
60 | /**
61 | * Memcachier password (from [dashboard](https://www.memcachier.com/caches)
62 | * or Heroku) for storage
63 | */
64 | MEMCACHIER_PASSWORD: string,
65 | }
66 |
67 | /**
68 | * A list of users who are currently banned across all BotCore instances
69 | */
70 | export type BannedUserList = string[];
71 |
72 | export type StringDict = { [key: string]: string };
73 |
74 | /**
75 | * @callback UsersCallback
76 | * @param err indicates errors (null if user retrieval is successful)
77 | * @param users list of IDs of users currently banned in the system
78 | */
79 | export type UsersCallback = (err: Error | null, users?: BannedUserList | null) => void;
80 |
81 | /**
82 | * @callback IsBannedCallback
83 | * @param isBanned true if the user is banned, false otherwise
84 | * @param users list of IDs of users currently banned in the system
85 | */
86 | export type IsBannedCallback = (isBanned: boolean, users?: string[] | null) => void;
87 |
88 | /**
89 | * @callback SuccessCallback
90 | * @param success true if the operation succeeded (i.e. the user was
91 | * banned or unbanned), false otherwise (if the user was already banned/
92 | * unbanned to begin with)
93 | */
94 | export type SuccessCallback = (success: boolean) => void;
95 |
96 | /**
97 | * @callback LoginCallback
98 | * @param err indicates errors (null if login is successful)
99 | * @param api null if login fails, see
100 | * [facebook-chat-api](https://github.com/Schmavery/facebook-chat-api) for details
101 | */
102 | export type LoginCallback = (err: Facebook.ILoginError, api: Facebook.API) => void;
103 |
104 | /**
105 | * @callback GenericErrCallback
106 | * @param err Message specifying the error (or null if none)
107 | */
108 | export type GenericErrCallback = (err: Error | null) => void;
109 |
110 | /**
111 | * @callback ErrDataCallback
112 | * @param err Message specifying the error (or null if none)
113 | * @param success Data returned from the successful operation
114 | */
115 |
116 | export type ErrDataCallback = (err: Error | null, data?: unknown) => void;
117 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */
4 | /* Basic Options */
5 | // "incremental": true, /* Enable incremental compilation */
6 | "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
7 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
8 | // "lib": [], /* Specify library files to be included in the compilation. */
9 | // "allowJs": true, /* Allow javascript files to be compiled. */
10 | // "checkJs": true, /* Report errors in .js files. */
11 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
12 | "declaration": true, /* Generates corresponding '.d.ts' file. */
13 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
14 | // "sourceMap": true, /* Generates corresponding '.map' file. */
15 | // "outFile": "./", /* Concatenate and emit output to single file. */
16 | "outDir": "./dist", /* Redirect output structure to the directory. */
17 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
18 | // "composite": true, /* Enable project compilation */
19 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
20 | // "removeComments": true, /* Do not emit comments to output. */
21 | // "noEmit": true, /* Do not emit outputs. */
22 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */
23 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
24 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
25 | /* Strict Type-Checking Options */
26 | "strict": true, /* Enable all strict type-checking options. */
27 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
28 | // "strictNullChecks": true, /* Enable strict null checks. */
29 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */
30 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
31 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
32 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
33 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
34 | /* Additional Checks */
35 | // "noUnusedLocals": true, /* Report errors on unused locals. */
36 | // "noUnusedParameters": true, /* Report errors on unused parameters. */
37 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
38 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
39 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
40 | // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
41 | /* Module Resolution Options */
42 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
43 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
44 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
45 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
46 | "typeRoots": [
47 | "./node_modules/@types",
48 | "./src"
49 | ], /* List of folders to include type definitions from. */
50 | // "types": [], /* Type declaration files to be included in compilation. */
51 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
52 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
53 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
54 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
55 | /* Source Map Options */
56 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
57 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
58 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
59 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
60 | /* Experimental Options */
61 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
62 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
63 | /* Advanced Options */
64 | "skipLibCheck": true, /* Skip type checking of declaration files. */
65 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
66 | }
67 | }
--------------------------------------------------------------------------------
/src/login.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Login API
3 | *
4 | * Provides various utilities for managing the login process, including
5 | * login/logout and import/export of appstate files.
6 | *
7 | * Encapsulates the login by caching the appstate in memory.
8 | *
9 | * @module login
10 | */
11 |
12 | import messenger from "facebook-chat-api"; // Chat API
13 | import { writeFileSync, readFile, writeFile } from "fs";
14 | import { ArgumentParser } from "argparse";
15 | import { Client } from "memjs";
16 | import { ErrDataCallback, GenericErrCallback, LoginCallback, LoginCredentials, StringDict } from "./types";
17 |
18 | // Default behavior: minimal logging and auto-approve recent logins
19 | const defaultOptions: Facebook.IOptions = {
20 | "logLevel": "error",
21 | "forceLogin": true,
22 | // TODO: Get rid of this option. We currently have to use this outdated user agent to force Facebook
23 | // to give us an older version of the login page that doesn't include new checks that break the API.
24 | "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Mobile Safari/537.36"
25 | };
26 |
27 | let mem: Client;
28 |
29 | /**
30 | * Call this to initialize the login module and log into Facebook using
31 | * [facebook-chat-api](https://github.com/Schmavery/facebook-chat-api).
32 | * See examples/ for example usage.
33 | *
34 | * @param credentials
35 | * @param callback called after login completed (successfully or unsuccessfully)
36 | * @param [forceCreds=false] if true, forces a login with credentials even if appstate exists
37 | * @param [options=defaultOptions] any options you wish to pass to the API on login;
38 | * by default, sets `logLevel` to `error` and `forceLogin` to `true` (auto-approves errors asking
39 | * for approval of recent logins for simplicity)
40 | */
41 | export const login = (credentials: LoginCredentials, callback: LoginCallback, forceCreds = false, options = defaultOptions): void => {
42 | // Initialize mem variable for external storage API (Memcachier)
43 | mem = Client.create(credentials.MEMCACHIER_SERVERS, {
44 | username: credentials.MEMCACHIER_USERNAME,
45 | password: credentials.MEMCACHIER_PASSWORD
46 | });
47 |
48 | // Login utility funcs
49 | function withAppstate(appstate: string, callback: LoginCallback) {
50 | console.log("Logging in with saved appstate...");
51 | messenger({
52 | appState: JSON.parse(appstate)
53 | }, options, (err, api) => {
54 | if (err) {
55 | withCreds(callback);
56 | } else {
57 | callback(err, api);
58 | }
59 | });
60 | }
61 | function withCreds(callback: LoginCallback) {
62 | console.log("Logging in with credentials...");
63 | if (!credentials.FACEBOOK_EMAIL || !credentials.FACEBOOK_PASSWORD) {
64 | return console.error("Fatal error: no login credentials provided");
65 | }
66 |
67 | messenger({
68 | email: credentials.FACEBOOK_EMAIL,
69 | password: credentials.FACEBOOK_PASSWORD
70 | }, options, (err, api) => {
71 | if (err) return console.error("Fatal error: failed login with credentials");
72 |
73 | mem.set("appstate", JSON.stringify(api.getAppState()), {}, merr => {
74 | if (err) {
75 | return console.error(merr);
76 | } else {
77 | callback(err, api);
78 | }
79 | });
80 | });
81 | }
82 |
83 | if (forceCreds) {
84 | // Force login with credentials
85 | withCreds(callback);
86 | } else {
87 | // Use stored appstate if exists, otherwise fallback to creds
88 | mem.get("appstate", (err, val) => {
89 | if (!err && val) {
90 | withAppstate(val.toString(), callback);
91 | } else {
92 | withCreds(callback);
93 | }
94 | });
95 | }
96 | };
97 |
98 | /**
99 | * Dumps the current login into a specified file.
100 | *
101 | * @param filename Name of the file specifying where to store the login
102 | * @param callback Callback to use after writing the file
103 | */
104 | export const dumpLogin = (filename: string, callback: GenericErrCallback): void => {
105 | mem.get("appstate", (err, val) => {
106 | if (!err && val) {
107 | writeFileSync(filename, val.toString());
108 | }
109 | callback(err);
110 | });
111 | };
112 |
113 | /**
114 | * Reads a new login into memory from a file.
115 | * @param filename Name of the file specifying where the imported login
116 | * is stored
117 | * @param callback Callback to use after reading the login
118 | */
119 | export const loadLogin = (filename: string, callback: GenericErrCallback): void => {
120 | readFile(filename, (err, val) => {
121 | if (!err) {
122 | mem.set("appstate", JSON.stringify(JSON.parse(val.toString())), {});
123 | }
124 | callback(err);
125 | });
126 | };
127 |
128 | /**
129 | * Logs out of Facebook.
130 | * @param callback
131 | */
132 | export const logout = (callback: ErrDataCallback): void => {
133 | mem.delete("appstate", err => {
134 | let success = true;
135 | if (err) {
136 | console.log(`Error logging out: ${err}`);
137 | success = false;
138 | } else {
139 | console.log("Logged out successfully.");
140 | }
141 | callback(err, success);
142 | });
143 | };
144 |
145 | /**
146 | * Converts a (NodeJS) facebook-chat-api appstate into a (Python) fbchat
147 | * session. See the examples/ directory for how this can be used to create
148 | * an fbchat bot with BotCore.
149 | *
150 | * @param filename Name of the file whose location contains the
151 | * appstate data to be converted
152 | * @param callback Callback to use after conversion completed,
153 | * passed the converted session
154 | */
155 | export const convert = (filename: string, callback: ErrDataCallback): void => {
156 | readFile(filename, (err, file) => {
157 | if (err) {
158 | callback(err);
159 | } else {
160 | // Extract the required information from the appstate
161 | const data = JSON.parse(file.toString());
162 | const attrs = ["c_user", "datr", "fr", "sb", "spin", "xs"];
163 | const output = attrs.reduce((obj: StringDict, key) => {
164 | obj[key] = searchAttribute(data, key);
165 | return obj;
166 | }, {});
167 | output["noscript"] = "1"; // Special attr
168 |
169 | callback(null, output);
170 | }
171 | });
172 | };
173 |
174 | /**
175 | * A variant of `convert` that directly outputs the converted session to a file.
176 | *
177 | * @param appstate Location of appstate to be converted
178 | * @param output Where to place the converted session
179 | * @param callback Callback called after conversion
180 | */
181 | export const convertToFile = (appstate: string, output: string, callback: GenericErrCallback): void => {
182 | convert(appstate, (err, session) => {
183 | if (err) {
184 | callback(err);
185 | } else {
186 | writeFile(output, JSON.stringify(session), null, callback);
187 | }
188 | });
189 | };
190 |
191 | /**
192 | * Exposes the underlying memjs memcache instance, which can be used for
193 | * temporary storage. Use wisely, or you may break your BotCore installation!
194 | *
195 | * > NOTE: if you call this before logging in with {@link login},
196 | * it will return nothing; the memcache is not initialized until you log in.
197 | *
198 | * @returns {Object} The underlying BotCore [memjs](https://memjs.netlify.app)
199 | * instance
200 | */
201 | export const getMemCache = (): Client => {
202 | return mem;
203 | };
204 |
205 | /**
206 | * facebook-chat-api appstates are an array of objects containing "key" and
207 | * "value" keys and additional properties (that the Python API doesn't use).
208 | *
209 | * This function searches and extracts the value for the given key, discarding
210 | * the other information.
211 | *
212 | * @param data facebook-chat-api appstate
213 | * @param key The key to locate
214 | * @returns {string} The value of the key (or null if not found)
215 | */
216 | function searchAttribute(data: Array, key: string): string {
217 | for (let i = 0; i < data.length; i++) {
218 | if (data[i].key == key) {
219 | return data[i].value;
220 | }
221 | }
222 | return "";
223 | }
224 |
225 | if (require.main === module) {
226 | const parser = new ArgumentParser({ add_help: true });
227 | parser.add_argument("--MEMCACHIER-USERNAME", { required: true });
228 | parser.add_argument("--MEMCACHIER-PASSWORD", { required: true });
229 | parser.add_argument("--MEMCACHIER-SERVERS", { required: true });
230 | parser.add_argument("--logout", { nargs: 0 });
231 | parser.add_argument("--dump-login", { nargs: 0 });
232 | parser.add_argument("--load-login", { nargs: 0 });
233 | parser.add_argument("--convert-login", { nargs: 0 });
234 | const args = parser.parse_args();
235 |
236 | login(args, () => {
237 | if (args.logout !== null) {
238 | logout(() => {
239 | process.exit();
240 | });
241 | } else if (args.dump_login !== null) {
242 | dumpLogin("appstate.json", () => {
243 | process.exit();
244 | });
245 | } else if (args.load_login !== null) {
246 | loadLogin("appstate.json", () => {
247 | process.exit();
248 | });
249 | } else if (args.convert_login !== null) {
250 | convertToFile("appstate.json", "session.txt", () => {
251 | process.exit();
252 | });
253 | } else {
254 | process.exit();
255 | }
256 | });
257 | }
258 |
--------------------------------------------------------------------------------
/docs/assets/js/search.js:
--------------------------------------------------------------------------------
1 | window.searchData = {"kinds":{"1":"Module","64":"Function","256":"Interface","1024":"Property","65536":"Type literal","4194304":"Type alias"},"rows":[{"id":0,"kind":1,"name":"banned","url":"modules/banned.html","classes":"tsd-kind-module"},{"id":1,"kind":64,"name":"getUsers","url":"modules/banned.html#getusers","classes":"tsd-kind-function tsd-parent-kind-module","parent":"banned"},{"id":2,"kind":64,"name":"isUser","url":"modules/banned.html#isuser","classes":"tsd-kind-function tsd-parent-kind-module","parent":"banned"},{"id":3,"kind":64,"name":"addUser","url":"modules/banned.html#adduser","classes":"tsd-kind-function tsd-parent-kind-module","parent":"banned"},{"id":4,"kind":64,"name":"removeUser","url":"modules/banned.html#removeuser","classes":"tsd-kind-function tsd-parent-kind-module","parent":"banned"},{"id":5,"kind":64,"name":"isMessage","url":"modules/banned.html#ismessage","classes":"tsd-kind-function tsd-parent-kind-module","parent":"banned"},{"id":6,"kind":1,"name":"login","url":"modules/login.html","classes":"tsd-kind-module"},{"id":7,"kind":64,"name":"login","url":"modules/login.html#login-1","classes":"tsd-kind-function tsd-parent-kind-module","parent":"login"},{"id":8,"kind":64,"name":"dumpLogin","url":"modules/login.html#dumplogin","classes":"tsd-kind-function tsd-parent-kind-module","parent":"login"},{"id":9,"kind":64,"name":"loadLogin","url":"modules/login.html#loadlogin","classes":"tsd-kind-function tsd-parent-kind-module","parent":"login"},{"id":10,"kind":64,"name":"logout","url":"modules/login.html#logout","classes":"tsd-kind-function tsd-parent-kind-module","parent":"login"},{"id":11,"kind":64,"name":"convert","url":"modules/login.html#convert","classes":"tsd-kind-function tsd-parent-kind-module","parent":"login"},{"id":12,"kind":64,"name":"convertToFile","url":"modules/login.html#converttofile","classes":"tsd-kind-function tsd-parent-kind-module","parent":"login"},{"id":13,"kind":64,"name":"getMemCache","url":"modules/login.html#getmemcache","classes":"tsd-kind-function tsd-parent-kind-module","parent":"login"},{"id":14,"kind":1,"name":"monitoring","url":"modules/monitoring.html","classes":"tsd-kind-module"},{"id":15,"kind":64,"name":"monitor","url":"modules/monitoring.html#monitor","classes":"tsd-kind-function tsd-parent-kind-module","parent":"monitoring"},{"id":16,"kind":64,"name":"cancelMonitoring","url":"modules/monitoring.html#cancelmonitoring","classes":"tsd-kind-function tsd-parent-kind-module","parent":"monitoring"},{"id":17,"kind":64,"name":"criticalError","url":"modules/monitoring.html#criticalerror","classes":"tsd-kind-function tsd-parent-kind-module","parent":"monitoring"},{"id":18,"kind":1,"name":"types","url":"modules/types.html","classes":"tsd-kind-module"},{"id":19,"kind":256,"name":"LoginCredentials","url":"interfaces/types.logincredentials.html","classes":"tsd-kind-interface tsd-parent-kind-module","parent":"types"},{"id":20,"kind":1024,"name":"FACEBOOK_EMAIL","url":"interfaces/types.logincredentials.html#facebook_email","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"types.LoginCredentials"},{"id":21,"kind":1024,"name":"FACEBOOK_PASSWORD","url":"interfaces/types.logincredentials.html#facebook_password","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"types.LoginCredentials"},{"id":22,"kind":1024,"name":"MEMCACHIER_SERVERS","url":"interfaces/types.logincredentials.html#memcachier_servers","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"types.LoginCredentials"},{"id":23,"kind":1024,"name":"MEMCACHIER_USERNAME","url":"interfaces/types.logincredentials.html#memcachier_username","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"types.LoginCredentials"},{"id":24,"kind":1024,"name":"MEMCACHIER_PASSWORD","url":"interfaces/types.logincredentials.html#memcachier_password","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"types.LoginCredentials"},{"id":25,"kind":4194304,"name":"BannedUserList","url":"modules/types.html#banneduserlist","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"types"},{"id":26,"kind":4194304,"name":"StringDict","url":"modules/types.html#stringdict","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"types"},{"id":27,"kind":65536,"name":"__type","url":"modules/types.html#stringdict.__type-4","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"types.StringDict"},{"id":28,"kind":4194304,"name":"UsersCallback","url":"modules/types.html#userscallback","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"types"},{"id":29,"kind":65536,"name":"__type","url":"modules/types.html#userscallback.__type-6","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"types.UsersCallback"},{"id":30,"kind":4194304,"name":"IsBannedCallback","url":"modules/types.html#isbannedcallback","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"types"},{"id":31,"kind":65536,"name":"__type","url":"modules/types.html#isbannedcallback.__type-2","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"types.IsBannedCallback"},{"id":32,"kind":4194304,"name":"SuccessCallback","url":"modules/types.html#successcallback","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"types"},{"id":33,"kind":65536,"name":"__type","url":"modules/types.html#successcallback.__type-5","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"types.SuccessCallback"},{"id":34,"kind":4194304,"name":"LoginCallback","url":"modules/types.html#logincallback","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"types"},{"id":35,"kind":65536,"name":"__type","url":"modules/types.html#logincallback.__type-3","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"types.LoginCallback"},{"id":36,"kind":4194304,"name":"GenericErrCallback","url":"modules/types.html#genericerrcallback","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"types"},{"id":37,"kind":65536,"name":"__type","url":"modules/types.html#genericerrcallback.__type-1","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"types.GenericErrCallback"},{"id":38,"kind":4194304,"name":"ErrDataCallback","url":"modules/types.html#errdatacallback","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"types"},{"id":39,"kind":65536,"name":"__type","url":"modules/types.html#errdatacallback.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"types.ErrDataCallback"}],"index":{"version":"2.3.9","fields":["name","parent"],"fieldVectors":[["name/0",[0,18.418]],["parent/0",[]],["name/1",[1,33.081]],["parent/1",[0,1.762]],["name/2",[2,33.081]],["parent/2",[0,1.762]],["name/3",[3,33.081]],["parent/3",[0,1.762]],["name/4",[4,33.081]],["parent/4",[0,1.762]],["name/5",[5,33.081]],["parent/5",[0,1.762]],["name/6",[6,14.623]],["parent/6",[]],["name/7",[6,14.623]],["parent/7",[6,1.399]],["name/8",[7,33.081]],["parent/8",[6,1.399]],["name/9",[8,33.081]],["parent/9",[6,1.399]],["name/10",[9,33.081]],["parent/10",[6,1.399]],["name/11",[10,33.081]],["parent/11",[6,1.399]],["name/12",[11,33.081]],["parent/12",[6,1.399]],["name/13",[12,33.081]],["parent/13",[6,1.399]],["name/14",[13,22.095]],["parent/14",[]],["name/15",[14,33.081]],["parent/15",[13,2.113]],["name/16",[15,33.081]],["parent/16",[13,2.113]],["name/17",[16,33.081]],["parent/17",[13,2.113]],["name/18",[17,13.622]],["parent/18",[]],["name/19",[18,33.081]],["parent/19",[17,1.303]],["name/20",[19,33.081]],["parent/20",[20,1.921]],["name/21",[21,33.081]],["parent/21",[20,1.921]],["name/22",[22,33.081]],["parent/22",[20,1.921]],["name/23",[23,33.081]],["parent/23",[20,1.921]],["name/24",[24,33.081]],["parent/24",[20,1.921]],["name/25",[25,33.081]],["parent/25",[17,1.303]],["name/26",[26,33.081]],["parent/26",[17,1.303]],["name/27",[27,16.987]],["parent/27",[28,3.164]],["name/28",[29,33.081]],["parent/28",[17,1.303]],["name/29",[27,16.987]],["parent/29",[30,3.164]],["name/30",[31,33.081]],["parent/30",[17,1.303]],["name/31",[27,16.987]],["parent/31",[32,3.164]],["name/32",[33,33.081]],["parent/32",[17,1.303]],["name/33",[27,16.987]],["parent/33",[34,3.164]],["name/34",[35,33.081]],["parent/34",[17,1.303]],["name/35",[27,16.987]],["parent/35",[36,3.164]],["name/36",[37,33.081]],["parent/36",[17,1.303]],["name/37",[27,16.987]],["parent/37",[38,3.164]],["name/38",[39,33.081]],["parent/38",[17,1.303]],["name/39",[27,16.987]],["parent/39",[40,3.164]]],"invertedIndex":[["__type",{"_index":27,"name":{"27":{},"29":{},"31":{},"33":{},"35":{},"37":{},"39":{}},"parent":{}}],["adduser",{"_index":3,"name":{"3":{}},"parent":{}}],["banned",{"_index":0,"name":{"0":{}},"parent":{"1":{},"2":{},"3":{},"4":{},"5":{}}}],["banneduserlist",{"_index":25,"name":{"25":{}},"parent":{}}],["cancelmonitoring",{"_index":15,"name":{"16":{}},"parent":{}}],["convert",{"_index":10,"name":{"11":{}},"parent":{}}],["converttofile",{"_index":11,"name":{"12":{}},"parent":{}}],["criticalerror",{"_index":16,"name":{"17":{}},"parent":{}}],["dumplogin",{"_index":7,"name":{"8":{}},"parent":{}}],["errdatacallback",{"_index":39,"name":{"38":{}},"parent":{}}],["facebook_email",{"_index":19,"name":{"20":{}},"parent":{}}],["facebook_password",{"_index":21,"name":{"21":{}},"parent":{}}],["genericerrcallback",{"_index":37,"name":{"36":{}},"parent":{}}],["getmemcache",{"_index":12,"name":{"13":{}},"parent":{}}],["getusers",{"_index":1,"name":{"1":{}},"parent":{}}],["isbannedcallback",{"_index":31,"name":{"30":{}},"parent":{}}],["ismessage",{"_index":5,"name":{"5":{}},"parent":{}}],["isuser",{"_index":2,"name":{"2":{}},"parent":{}}],["loadlogin",{"_index":8,"name":{"9":{}},"parent":{}}],["login",{"_index":6,"name":{"6":{},"7":{}},"parent":{"7":{},"8":{},"9":{},"10":{},"11":{},"12":{},"13":{}}}],["logincallback",{"_index":35,"name":{"34":{}},"parent":{}}],["logincredentials",{"_index":18,"name":{"19":{}},"parent":{}}],["logout",{"_index":9,"name":{"10":{}},"parent":{}}],["memcachier_password",{"_index":24,"name":{"24":{}},"parent":{}}],["memcachier_servers",{"_index":22,"name":{"22":{}},"parent":{}}],["memcachier_username",{"_index":23,"name":{"23":{}},"parent":{}}],["monitor",{"_index":14,"name":{"15":{}},"parent":{}}],["monitoring",{"_index":13,"name":{"14":{}},"parent":{"15":{},"16":{},"17":{}}}],["removeuser",{"_index":4,"name":{"4":{}},"parent":{}}],["stringdict",{"_index":26,"name":{"26":{}},"parent":{}}],["successcallback",{"_index":33,"name":{"32":{}},"parent":{}}],["types",{"_index":17,"name":{"18":{}},"parent":{"19":{},"25":{},"26":{},"28":{},"30":{},"32":{},"34":{},"36":{},"38":{}}}],["types.errdatacallback",{"_index":40,"name":{},"parent":{"39":{}}}],["types.genericerrcallback",{"_index":38,"name":{},"parent":{"37":{}}}],["types.isbannedcallback",{"_index":32,"name":{},"parent":{"31":{}}}],["types.logincallback",{"_index":36,"name":{},"parent":{"35":{}}}],["types.logincredentials",{"_index":20,"name":{},"parent":{"20":{},"21":{},"22":{},"23":{},"24":{}}}],["types.stringdict",{"_index":28,"name":{},"parent":{"27":{}}}],["types.successcallback",{"_index":34,"name":{},"parent":{"33":{}}}],["types.userscallback",{"_index":30,"name":{},"parent":{"29":{}}}],["userscallback",{"_index":29,"name":{"28":{}},"parent":{}}]],"pipeline":[]}}
--------------------------------------------------------------------------------
/docs/modules/monitoring.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | monitoring | messenger-botcore
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
Provides a basic utility for monitoring a running bot process. It is
74 | configurable, with options to notify a maintainer if the bot goes down,
75 | automatically retry logins for stale processes, and restart the bot process
76 | entirely if all else fails.
A callback to send a new API
204 | instance to if login failed and a re-attempted login succeeded (optional –
205 | omitting this callback is equivalent to disabling the retry login feature)
Provides various utilities for universally banning/unbanning users across
74 | any number of bot instances
75 |
Note: because this API relies on the data store initialized in the login
76 | module, none of its functions will work unless you've logged in already
77 | via a call to login.login.
The LoginCredentials object is required for logging in to any application using BotCore. The
77 | idea of it is to store your (sensitive) credentials separately from the source of your project, in a
78 | place that won't be accidentally committed to a repo and published for the world to see. It consists
79 | of several required keys that allow BotCore to log in to both Facebook and the MemCachier service
80 | (used to cache logins) on your behalf. The keys are listed and explained below.
81 |
82 |
NOTE: to obtain the values for the MEMCACHIER_ variables, you must sign up for a free
83 | MemCachier account and create a cache. From there, you
84 | will be able to retrieve the requisite info from your dashboard.
85 |
86 |
I recommend the following two methods for storing your credentials object due to their ease of use:
87 |
88 |
Environment variables: you can store these keys as environment variables, which will prevent
89 | them from being stored in any file in your project. When logging in, simply pass process.env as your
90 | credentials object, because it will contain all of the required keys needed to log in successfully!
91 | You can find an example of how to configure your credentials this way in examples/credentials.sh
92 | in the BotCore repo.
93 |
94 |
A gitignored credentials file: you can create a file (credentials.js or similar) that contains
95 | all of your required credentials keys as exported variables, and then simply import this as a JS
96 | module wherever you need to log in. Don't forget to add this credentials file to your .gitignore
97 | so that your credentials aren't exposed! You can find an example of how to configure your credentials
98 | this way in examples/credentials.js in the BotCore repo.
99 |
100 |
101 |
These are two of many possible ways you could choose to store this information. Keep in mind that
102 | regardless of which method you choose, you will have to eventually pass a JavaScript object containing
103 | the following keys to the login function, so you will need to be able to access this
104 | information at runtime.
105 |
Also keep in mind that the FACEBOOK_EMAIL and FACEBOOK_PASSWORD keys are only required for login
106 | if you do not have an active Facebook login session stored in BotCore (i.e. you have logged in
107 | recently, and Facebook hasn't decided to terminate your session yet). BotCore caches your recent
108 | logins to prevent too many hard (username/password) logins, unless you use the forceLogin option.
109 | If you are using several bots with BotCore, consider storing your FACEBOOK_EMAIL and
110 | FACEBOOK_PASSWORD keys with only one of them, and only using your MEMCACHIER_ variables to log in
111 | from other bots.
Converts a (NodeJS) facebook-chat-api appstate into a (Python) fbchat
115 | session. See the examples/ directory for how this can be used to create
116 | an fbchat bot with BotCore.
117 |
118 |
119 |
Parameters
120 |
121 |
122 |
filename: string
123 |
124 |
Name of the file whose location contains the
125 | appstate data to be converted
true if the operation succeeded (i.e. the user was
313 | banned or unbanned), false otherwise (if the user was already banned/
314 | unbanned to begin with)
Monitoring API
72 |Provides a basic utility for monitoring a running bot process. It is 74 | configurable, with options to notify a maintainer if the bot goes down, 75 | automatically retry logins for stale processes, and restart the bot process 76 | entirely if all else fails.
77 |