From 3b22f1e1a56f2980e84c381ed1c8ed66d77fd3eb Mon Sep 17 00:00:00 2001 From: bangHasan Date: Tue, 20 Apr 2021 03:31:01 +0700 Subject: [PATCH] v0.3.8 verbosLevel --- .gitignore | 2 +- README.md | 2 + app.js | 2 +- config_sample.js | 6 +- doc/history.md | 10 +- doc/tdlib.md | 30 ++ module/client.js | 18 +- tdlib/readme.md | 21 -- tdlib/td.node | Bin 102896 -> 0 bytes tdlib/tdl/client.js | 671 -------------------------------------- tdlib/tdl/fluture.js | 20 -- tdlib/tdl/index.js | 35 -- tdlib/tdl/prompt-stubs.js | 30 -- tdlib/tdl/prompt.js | 36 -- tdlib/tdl/types.js | 1 - tdlib/tdl/util.js | 72 ---- tdlib/tdl/uuidv4.js | 30 -- tdlib/tdlib.js | 88 ----- 18 files changed, 55 insertions(+), 1019 deletions(-) create mode 100644 doc/tdlib.md delete mode 100644 tdlib/readme.md delete mode 100755 tdlib/td.node delete mode 100644 tdlib/tdl/client.js delete mode 100644 tdlib/tdl/fluture.js delete mode 100644 tdlib/tdl/index.js delete mode 100644 tdlib/tdl/prompt-stubs.js delete mode 100644 tdlib/tdl/prompt.js delete mode 100644 tdlib/tdl/types.js delete mode 100644 tdlib/tdl/util.js delete mode 100644 tdlib/tdl/uuidv4.js delete mode 100644 tdlib/tdlib.js diff --git a/.gitignore b/.gitignore index cbed4e5..82221b7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ data_userbot/ data_botapi/ bak/ -#data/* +data/* # Logs logs diff --git a/README.md b/README.md index 84bb64e..bea0a67 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,8 @@ Jika menggunakan OS lain, compile sendiri ya. Setingan diletakkan pada `config.js` +Detail baca di halaman [TDLib](https://github.com/banghasan/hsubot/blob/main/doc/tdlib.md) + #### Android Download [https://core.telegram.org/tdlib/tdlib.zip](https://core.telegram.org/tdlib/tdlib.zip) diff --git a/app.js b/app.js index d9b3856..02c8e88 100644 --- a/app.js +++ b/app.js @@ -1,6 +1,6 @@ module.exports = { nama: 'HSUBot', - versi: '0.3.7b', + versi: '0.3.8b', programmer: 'Hasanudin H Syafaat', email: 'banghasan@gmail.com', telegram: '@hasanudinhs', diff --git a/config_sample.js b/config_sample.js index 1857501..9af2d4d 100644 --- a/config_sample.js +++ b/config_sample.js @@ -20,14 +20,16 @@ module.exports = { admin: { active: true, // <-- aktifkan jika ingin membatasi bot dipergunakan oleg admin saja - id: [123456], // jika skipme false, dan admin true.. id bot harus dimasukkan di sini + id: [ // jika skipme false, dan admin true.. id bot harus dimasukkan di sini + 213567634, + ], }, // detail aplikasi // untuk keperluan plugins base: { - uploadPath : '', + uploadPath: '', }, // override plugins status diff --git a/doc/history.md b/doc/history.md index f304d9b..2cc7042 100644 --- a/doc/history.md +++ b/doc/history.md @@ -16,13 +16,21 @@ First Rilis `18 April 2021` + [.3.6] TGLib v1.2: sendAction, getMessage. + [.3.6] Firmware: example sendAction impl. file -v.0.3.7, 19 April 2021 +v.0.3.7, `19 April 2021` + [.3.7] Config: overide status plugins. Update Example Config. + [.3.7] Plugins: +upload (Foto, Video, Doc, dll), +bash + [.3.7] Helper: bug fixes + [.3.7] TGLib v1.2.1: bug fix, fileType untuk localFileinput +v.0.3.8, `20 April 2021` + ++ Login nomor jadi bersih, set debug level ke `0`. Jika ingin mendebug, naikkan levelnya. ++ Bugfixes ++ [.3.8] Config: Debug level bereffect ke verbosityLevel ++ [.3.8] Membersihkan file tidak dipakai + + ### v0.2 a `17 April 2021` diff --git a/doc/tdlib.md b/doc/tdlib.md new file mode 100644 index 0000000..2bfbbc0 --- /dev/null +++ b/doc/tdlib.md @@ -0,0 +1,30 @@ +## TDLib + +Bisa build sendiri dengan mengikuti petunjuk: + +[https://github.com/tdlib/td#building](https://github.com/tdlib/td#building) + +### Generator + +[https://tdlib.github.io/td/build.html](https://tdlib.github.io/td/build.html) + +### Android + +Download [https://core.telegram.org/tdlib/tdlib.zip](https://core.telegram.org/tdlib/tdlib.zip) + +### Versi Ini + +Aku build di server ubuntu 20.04, tanggal 31 Maret 2021 + +Versi 1.7.3 + +### Versi Lama + +Download Pre-built versi lain: [https://github.com/ForNeVeR/tdlib.native/releases](https://github.com/ForNeVeR/tdlib.native/releases) + +## Support + +Hasanudin H Syafaat +banghasan@gmail.com + +[@botindonesia](https://t.me/botindonesia) \ No newline at end of file diff --git a/module/client.js b/module/client.js index b29774d..615d844 100644 --- a/module/client.js +++ b/module/client.js @@ -1,30 +1,28 @@ const { Client } = require('tdl') const { TDLib } = require('tdl-tdlib-addon') -// const { Client } = require('../tdlib/tdl') -// const { TDLib } = require('../tdlib/tdlib') -const { API_ID, API_HASH, BOT_TOKEN, BOT_API, pathTDLib } = require('../config.js'); +const CONFIG = require('../config.js'); const APP = require('../app.js'); // add timestamps in front of log messages require('console-stamp')(console, 'HH:MM:ss.l'); const API_BOT_AUTH = { type: 'bot', - token: BOT_TOKEN, // in document say write this line but - getToken: () => BOT_TOKEN // if this line dont set pakase get error and dont work + token: CONFIG.BOT_TOKEN, // in document say write this line but + getToken: () => CONFIG.BOT_TOKEN // if this line dont set pakase get error and dont work } -let pathData = BOT_API ? './data_botapi' : './data_userbot' +let pathData = CONFIG.BOT_API ? './data_botapi' : './data_userbot' -const tdlib = new TDLib(pathTDLib) +const tdlib = new TDLib(CONFIG.pathTDLib) const client = new Client(tdlib, { - apiId: API_ID, - apiHash: API_HASH, + apiId: CONFIG.API_ID, + apiHash: CONFIG.API_HASH, databaseDirectory: pathData + '/_td_database', filesDirectory: pathData + '/_td_files', skipOldUpdates: true, - verbosityLevel: 2, + verbosityLevel: CONFIG.debug.level, tdlibParameters: { enable_storage_optimizer: true, diff --git a/tdlib/readme.md b/tdlib/readme.md deleted file mode 100644 index 3ed7bf7..0000000 --- a/tdlib/readme.md +++ /dev/null @@ -1,21 +0,0 @@ -## TDLib - -Folder lokasi TDLib - -### Android - -Download [https://core.telegram.org/tdlib/tdlib.zip](https://core.telegram.org/tdlib/tdlib.zip) - -### Prebuilt - -Aku build di server ubuntu 20.04, tanggal 31 Maret 2021 - -Versi 1.7.3 - -Hasanudin H Syafaat -banghasan@gmail.com - - -## Support - -[@botindonesia](https://t.me/botindonesia) \ No newline at end of file diff --git a/tdlib/td.node b/tdlib/td.node deleted file mode 100755 index 03757f4080eabd12b157f07dd5361ff874c686f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102896 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 diff --git a/tdlib/tdl/client.js b/tdlib/tdl/client.js deleted file mode 100644 index 9661aca..0000000 --- a/tdlib/tdl/client.js +++ /dev/null @@ -1,671 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.Client = exports.TdlError = void 0; - -var _path = require("path"); - -var _eventemitter = _interopRequireDefault(require("eventemitter3")); - -var _debug = _interopRequireDefault(require("debug")); - -var _uuidv = _interopRequireDefault(require("./uuidv4")); - -var _util = require("./util"); - -var _prompt = require("./prompt"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const debug = (0, _debug.default)('tdl:client'); -// const debug = ()=>{}; -const debugEmitter = (0, _debug.default)('tdl:client:emitter'); -const debugRes = (0, _debug.default)('tdl:client:response'); -const debugReq = (0, _debug.default)('tdl:client:request'); -const defaultLoginDetails = { - type: 'user', - getPhoneNumber: _prompt.getPhoneNumber, - getAuthCode: _prompt.getAuthCode, - getPassword: _prompt.getPassword, - getName: _prompt.getName -}; -const defaultOptions = { - databaseDirectory: '_td_database', - filesDirectory: '_td_files', - databaseEncryptionKey: '', - verbosityLevel: 2, - receiveTimeout: 10, - skipOldUpdates: false, - useTestDc: false, - useMutableRename: false, - useDefaultVerbosityLevel: false, - disableAuth: false, - tdlibParameters: { - use_message_database: true, - use_secret_chats: false, - system_language_code: 'en', - application_version: '1.0', - device_model: 'Unknown device', - system_version: 'Unknown', - enable_storage_optimizer: true - } -}; - -class TdlDeferred { - constructor() { - _defineProperty(this, "_innerDefer", void 0); - - _defineProperty(this, "_done", false); - } - - // Not done or defer not set - isPending() { - return !this._done; - } - - isDone() { - return this._done; - } - - isDeferSet() { - return this._innerDefer != null; - } - - setDefer(defer) { - this._innerDefer = defer; - } - - resolve(result) { - if (this._done || !this._innerDefer) return; - this._done = true; - - this._innerDefer.resolve(result); - } - - reject(error) { - if (this._done || !this._innerDefer) return; - this._done = true; - - this._innerDefer.reject(error); - } - -} - -class TdlError extends Error { - constructor(err, msg) { - super(msg); - - _defineProperty(this, "err", void 0); - - this.err = err; - } - -} - -exports.TdlError = TdlError; - -const empty = () => ({}); - -function invariant(cond, msg) { - if (!cond) throw new Error(msg); -} - -const TDL_MAGIC = '6c47e6b71ea'; - -class Client { - constructor(tdlibInstance, options = {}) { - _defineProperty(this, "_options", void 0); - - _defineProperty(this, "_emitter", new _eventemitter.default()); - - _defineProperty(this, "_fetching", new Map()); - - _defineProperty(this, "_tdlib", void 0); - - _defineProperty(this, "_client", void 0); - - _defineProperty(this, "_connectionState", { - _: 'connectionStateConnecting' - }); - - _defineProperty(this, "_connectDefer", new TdlDeferred()); - - _defineProperty(this, "_authNeeded", false); - - _defineProperty(this, "_loginDetails", void 0); - - _defineProperty(this, "_loginDefer", new TdlDeferred()); - - _defineProperty(this, "_paused", false); - - _defineProperty(this, "_initialized", false); - - _defineProperty(this, "getBackendName", () => { - return this._tdlib.getName(); - }); - - _defineProperty(this, "connect", () => { - return new Promise((resolve, reject) => { - if (this._initialized) { - const err = this._client ? Error('The client is already initialized') : Error('Cannot re-initialize a destroyed client'); - return reject(err); - } - - this._connectDefer.setDefer({ - resolve, - reject - }); - - this._init(); - }); - }); - - _defineProperty(this, "login", (getLoginDetails = empty) => { - debug('client.login()'); - - this._emitter.once('auth-needed', () => { - this._loginDetails = (0, _util.mergeDeepRight)(defaultLoginDetails, getLoginDetails()); - debug('set _loginDetails to', this._loginDetails); - }); - - return new Promise((resolve, reject) => { - this._loginDefer.setDefer({ - resolve, - reject - }); - - this._emitter.emit('_login'); - }); - }); - - _defineProperty(this, "connectAndLogin", async (fn = empty) => { - await this.connect(); - return this.login(fn); - }); - - _defineProperty(this, "pause", () => { - if (!this._paused) { - debug('pause'); - this._paused = true; - } else { - debug('pause (no-op)'); - } - }); - - _defineProperty(this, "resume", () => { - if (this._paused) { - debug('resume'); - this._paused = false; - - this._emitter.emit('_resume'); - } else { - debug('resume (no-op)'); - } - }); - - _defineProperty(this, "on", (event, listener) => { - this._emitter.on(event, listener); - - return this; - }); - - _defineProperty(this, "once", (event, listener) => { - this._emitter.once(event, listener); - - return this; - }); - - _defineProperty(this, "off", (event, listener, once = false) => { - this._emitter.removeListener(event, listener, undefined, once); - }); - - _defineProperty(this, "addListener", this.on); - - _defineProperty(this, "removeListener", this.off); - - _defineProperty(this, "emit", (event, value) => { - debugEmitter('emit', event, value); - - this._emitter.emit(event, value); - }); - - _defineProperty(this, "invoke", async request => { - const id = (0, _uuidv.default)(); // $FlowIgnore[prop-missing] - - request['@extra'] = id; - const receiveResponse = new Promise((resolve, reject) => { - // This promise must not be rejected with values other than Td$error - // for Fluture types to be correct - try { - const defer = { - resolve, - reject - }; - - this._fetching.set(id, defer); - } catch (e) { - this._catchError(new TdlError(e)); - } - }); - - this._send(request); - - return receiveResponse; - }); - - _defineProperty(this, "destroy", () => { - if (!this._client) return; - - this._tdlib.destroy(this._client); - - this._client = null; - this.resume(); - this.emit('destroy'); - }); - - _defineProperty(this, "close", () => { - debug('close'); - return new Promise(resolve => { - if (!this._client) return resolve(); // TODO: call this.resume() here? - // If the client is paused, we can't receive authorizationStateClosed - // and destroy won't be called - - this._sendTdl({ - _: 'close' - }); - - this._emitter.once('destroy', () => resolve()); - }); - }); - - _defineProperty(this, "setLogFatalErrorCallback", fn => { - this._tdlib.setLogFatalErrorCallback(fn); - }); - - _defineProperty(this, "execute", request => { - debugReq('execute', request); - if (!this._client) return null; - const { - _client: client - } = this; - const tdRequest = (0, _util.deepRenameKey)('_', '@type', request); - - const tdResponse = this._tdlib.execute(client, tdRequest); - - return tdResponse && (0, _util.deepRenameKey)('@type', '_', tdResponse); - }); - - this._options = (0, _util.mergeDeepRight)(defaultOptions, options); - if (!options.apiId) throw new TypeError('Valid api_id must be provided.'); - if (!options.apiHash) throw new TypeError('Valid api_hash must be provided.'); - this._tdlib = tdlibInstance; - } - - static create(tdlibInstance, options = {}) { - return new Client(tdlibInstance, options); - } - - _catchError(err) { - debug('catchError', err); - - const fn = d => d.isPending(); - - const defers = [this._connectDefer, this._loginDefer].filter(fn); - - if (defers.length === 0) { - this.emit('error', err); - return; - } - - for (const deferred of defers) deferred.reject(err); - } - - _rejectConnectAndLogin(err) { - this._connectDefer.reject(err); - - this._loginDefer.reject(err); - } - - _init() { - try { - if (!this._options.useDefaultVerbosityLevel) { - debug('_init: setLogVerbosityLevel', this._options.verbosityLevel); - - this._tdlib.execute(null, { - '@type': 'setLogVerbosityLevel', - new_verbosity_level: this._options.verbosityLevel - }); - } - - this._client = this._tdlib.create(); - } catch (e) { - this._catchError(new TdlError(e, 'Error while creating client')); - - return; - } - - this._initialized = true; - if (this._options.disableAuth) this._connectDefer.resolve(); - - this._loop().catch(e => this._catchError(new TdlError(e))); - } - - // Wait until the 'login' function is called - _waitLogin() { - debug('waitLogin', this._loginDefer); - return new Promise(resolve => { - if (this._loginDefer.isDeferSet()) return resolve(); - - this._emitter.once('_login', () => resolve()); - }); - } - - _authHasNeeded() { - if (this._authNeeded) { - invariant(this._loginDetails != null, '_authHasNeeded: (_authNeeded true) loginDetails should be set'); - return this._loginDetails; - } - - this._authNeeded = true; - this.emit('auth-needed'); - invariant(this._loginDetails != null, '_authHasNeeded: (_authNeeded false) loginDetails should be set'); - return this._loginDetails; - } - - // Wait until the 'resume' function is called - _waitResume() { - return new Promise(resolve => { - if (!this._paused) resolve(); - - this._emitter.once('_resume', () => resolve()); - }); - } - - _send(request) { - debugReq('send', request); - if (!this._client) return; - const { - _client: client - } = this; - const tdRequest = (0, _util.deepRenameKey)('_', '@type', request); - - this._tdlib.send(client, tdRequest); - } - - _sendTdl(request) { - // $FlowIgnore[prop-missing] - this._send(_objectSpread(_objectSpread({}, request), {}, { - '@extra': TDL_MAGIC - })); - } - - async _receive(timeout = this._options.receiveTimeout) { - if (!this._client) return null; - const tdResponse = await this._tdlib.receive(this._client, timeout); // Note: Immutable rename is used to preserve key order (for better logs) - - return tdResponse && (this._options.useMutableRename ? (0, _util.deepRenameKey_)('@type', '_', tdResponse) : (0, _util.deepRenameKey)('@type', '_', tdResponse)); - } - - async _loop() { - while (true) { - try { - if (this._paused) { - debug('receive loop: waiting for resume'); - await this._waitResume(); - debug('receive loop: resumed'); - } - - if (!this._client) { - debug('receive loop: no client'); - break; - } - - const response = await this._receive(); - if (response) await this._handleResponse(response);else debug('receive loop: response is empty'); - } catch (e) { - this._catchError(new TdlError(e)); - } - } - - debug('receive loop: end'); - } - - async _handleResponse(res) { - this.emit('response', res); - debugRes(res); - if (res._ === 'error') return this._handleError(res); - const id = res['@extra']; - - const defer = this._fetching.get(id); - - if (defer) { - delete res['@extra']; - defer.resolve(res); - - this._fetching.delete(id); - } else if (id !== TDL_MAGIC) { - return this._handleUpdate(res); - } else { - debug('(TDL_MAGIC) Not emitting response', res); - } - } - - async _handleUpdate(update) { - // updateOption, updateConnectionState, updateAuthorizationState - // are always emitted, even with skipOldUpdates set to true - switch (_) { - case 'updateOption': - debug('Option:', update); - this.emit('update', update); - return; - - case 'updateConnectionState': - debug('New connection state:', state); - this._connectionState = state; - this.emit('update', update); - return; - - case 'updateAuthorizationState': - debug('New authorization state:', authorization_state._); - this.emit('update', update); - if (!this._options.disableAuth) this._handleAuth(update).catch(e => this._catchError(new TdlError(e))); - return; - - default: - const shouldSkip = this._options.skipOldUpdates && this._connectionState._ === 'connectionStateUpdating'; - if (shouldSkip) return; - this.emit('update', update); - } - } - - async _handleAuth(update) { - const authorizationState = authorization_state; - - switch (authorizationState._) { - case 'authorizationStateWaitTdlibParameters': - return this._sendTdl({ - _: 'setTdlibParameters', - 'parameters': _objectSpread(_objectSpread({ - database_directory: (0, _path.resolve)(this._options.databaseDirectory), - files_directory: (0, _path.resolve)(this._options.filesDirectory), - api_id: this._options.apiId, - api_hash: this._options.apiHash, - use_test_dc: this._options.useTestDc - }, this._options.tdlibParameters), {}, { - _: 'tdlibParameters' - }) - }); - - case 'authorizationStateWaitEncryptionKey': - this._sendTdl({ - _: 'checkDatabaseEncryptionKey', - encryption_key: this._options.databaseEncryptionKey - }); - - return this._connectDefer.resolve(); - - case 'authorizationStateClosed': - this._rejectConnectAndLogin(Error('Received authorizationStateClosed')); - - return this.destroy(); - - case 'authorizationStateReady': - if (!this._authNeeded) this.emit('auth-not-needed'); - } - - await this._waitLogin(); - debug('waitLogin end', authorizationState._); // TODO: Handle authorizationStateWaitOtherDeviceConfirmation? - - switch (authorizationState._) { - case 'authorizationStateWaitPhoneNumber': - { - const loginDetails = this._authHasNeeded(); - - switch (loginDetails.type) { - case 'user': - return this._sendTdl({ - _: 'setAuthenticationPhoneNumber', - phone_number: await loginDetails.getPhoneNumber(false) - }); - - case 'bot': - return this._sendTdl({ - _: 'checkAuthenticationBotToken', - token: await loginDetails.getToken(false) - }); - } - } - - case 'authorizationStateWaitCode': - { - const loginDetails = this._authHasNeeded(); - - if (loginDetails.type !== 'user') return; - const code = await loginDetails.getAuthCode(false); - return this._sendTdl({ - _: 'checkAuthenticationCode', - code - }); - } - - case 'authorizationStateWaitRegistration': - { - const loginDetails = this._authHasNeeded(); - - if (loginDetails.type !== 'user') return; - const { - firstName, - lastName = '' - } = await loginDetails.getName(); - return this._sendTdl({ - _: 'registerUser', - first_name: firstName, - last_name: lastName - }); - } - - case 'authorizationStateWaitPassword': - { - const loginDetails = this._authHasNeeded(); - - if (loginDetails.type !== 'user') return; - const passwordHint = authorizationState.password_hint; - const password = await loginDetails.getPassword(passwordHint, false); - return this._sendTdl({ - _: 'checkAuthenticationPassword', - password - }); - } - - case 'authorizationStateReady': - return this._loginDefer.resolve(); - } - } - - _emitErrWithoutExtra(error) { - // $FlowIgnore[prop-missing] - delete error['@extra']; - - this._catchError(error); - } - - async _handleError(error) { - // $FlowIgnore[prop-missing] - const id = error['@extra']; - - const defer = this._fetching.get(id); - - if (defer) { - // $FlowIgnore[prop-missing] - delete error['@extra']; - defer.reject(error); - - this._fetching.delete(id); - } else if (id === TDL_MAGIC) { - const loginDetails = this._loginDetails; - if (!loginDetails) return this._emitErrWithoutExtra(error); - - switch (loginDetails.type) { - case 'user': - return this._handleUserError(error, loginDetails); - - case 'bot': - return this._handleBotError(error, loginDetails); - } - } else { - this.emit('error', error); - } - } - - async _handleUserError(error, loginDetails) { - switch (error.message) { - case 'PHONE_CODE_EMPTY': - case 'PHONE_CODE_INVALID': - return this._sendTdl({ - _: 'checkAuthenticationCode', - code: await loginDetails.getAuthCode(true) - }); - - case 'PHONE_NUMBER_INVALID': - return this._sendTdl({ - _: 'setAuthenticationPhoneNumber', - phone_number: await loginDetails.getPhoneNumber(true) - }); - - case 'PASSWORD_HASH_INVALID': - return this._sendTdl({ - _: 'checkAuthenticationPassword', - password: await loginDetails.getPassword('', true) - }); - - default: - this._emitErrWithoutExtra(error); - - } - } - - async _handleBotError(error, loginDetails) { - switch (error.message) { - case 'ACCESS_TOKEN_INVALID': - return this._sendTdl({ - _: 'checkAuthenticationBotToken', - token: await loginDetails.getToken(true) - }); - - default: - this._emitErrWithoutExtra(error); - - } - } - -} - -exports.Client = Client; \ No newline at end of file diff --git a/tdlib/tdl/fluture.js b/tdlib/tdl/fluture.js deleted file mode 100644 index 5f5b7f1..0000000 --- a/tdlib/tdl/fluture.js +++ /dev/null @@ -1,20 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.tryP = void 0; - -const tryP = (() => { - try { - const fluture = require('fluture'); - - return fluture.tryP; - } catch (e) { - return () => { - throw new Error('Fluture not found'); - }; - } -})(); - -exports.tryP = tryP; \ No newline at end of file diff --git a/tdlib/tdl/index.js b/tdlib/tdl/index.js deleted file mode 100644 index a4329f2..0000000 --- a/tdlib/tdl/index.js +++ /dev/null @@ -1,35 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "Client", { - enumerable: true, - get: function () { - return _client.Client; - } -}); -Object.defineProperty(exports, "TDL", { - enumerable: true, - get: function () { - return _client.Client; - } -}); -Object.defineProperty(exports, "Tdl", { - enumerable: true, - get: function () { - return _client.Client; - } -}); -Object.defineProperty(exports, "TdlError", { - enumerable: true, - get: function () { - return _client.TdlError; - } -}); -exports.default = void 0; - -var _client = require("./client"); - -var _default = _client.Client; -exports.default = _default; \ No newline at end of file diff --git a/tdlib/tdl/prompt-stubs.js b/tdlib/tdl/prompt-stubs.js deleted file mode 100644 index 01f60ab..0000000 --- a/tdlib/tdl/prompt-stubs.js +++ /dev/null @@ -1,30 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getName = exports.getPassword = exports.getAuthCode = exports.getPhoneNumber = void 0; - -const getPhoneNumber = () => { - throw new Error('Default getPhoneNumber is not supported'); -}; - -exports.getPhoneNumber = getPhoneNumber; - -const getAuthCode = () => { - throw new Error('Default getAuthCode is not supported'); -}; - -exports.getAuthCode = getAuthCode; - -const getPassword = () => { - throw new Error('Default getPassword is not supported'); -}; - -exports.getPassword = getPassword; - -const getName = () => { - throw new Error('Default getName is not supported'); -}; - -exports.getName = getName; \ No newline at end of file diff --git a/tdlib/tdl/prompt.js b/tdlib/tdl/prompt.js deleted file mode 100644 index 585f3a5..0000000 --- a/tdlib/tdl/prompt.js +++ /dev/null @@ -1,36 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getName = exports.getPassword = exports.getAuthCode = exports.getPhoneNumber = void 0; - -// var promptly = _interopRequireWildcard(require("promptly")); -var promptly = _interopRequireWildcard(require("heroku-cli-util")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -const getPhoneNumber = retry => promptly.prompt(retry ? 'Invalid phone number, please re-enter: ' : 'Please enter phone number: '); - -exports.getPhoneNumber = getPhoneNumber; - -const getAuthCode = retry => promptly.prompt(retry ? 'Wrong auth code, please re-enter: ' : 'Please enter auth code: '); - -exports.getAuthCode = getAuthCode; - -const getPassword = (passwordHint, retry) => promptly.password(retry ? 'Wrong password, please re-enter: ' : `Please enter password (${passwordHint}): `, { - replace: '*' -}); - -exports.getPassword = getPassword; - -const getName = async () => ({ - firstName: await promptly.prompt('First name:'), - lastName: await promptly.prompt('Last name (optional):', { - default: undefined - }) -}); - -exports.getName = getName; \ No newline at end of file diff --git a/tdlib/tdl/types.js b/tdlib/tdl/types.js deleted file mode 100644 index 9a390c3..0000000 --- a/tdlib/tdl/types.js +++ /dev/null @@ -1 +0,0 @@ -"use strict"; \ No newline at end of file diff --git a/tdlib/tdl/util.js b/tdlib/tdl/util.js deleted file mode 100644 index 75161a2..0000000 --- a/tdlib/tdl/util.js +++ /dev/null @@ -1,72 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.mergeDeepRight = mergeDeepRight; -exports.deepRenameKey = deepRenameKey; -exports.deepRenameKey_ = deepRenameKey_; - -function isObject(item) { - return item != null && typeof item === 'object' && !Array.isArray(item); -} - -function mergeDeepRight(obj1, obj2) { - if (isObject(obj1) && isObject(obj2)) { - const result = {}; - - for (const key2 in obj2) { - const val1 = obj1[key2]; - const val2 = obj2[key2]; - result[key2] = mergeDeepRight(val1, val2); - } - - for (const key1 in obj1) { - if (!(key1 in result)) result[key1] = obj1[key1]; - } - - return result; - } - - return obj2; -} - -function deepRenameValue(oldKey, newKey, v) { - if (Array.isArray(v)) return v.map(x => deepRenameValue(oldKey, newKey, x)); - if (typeof v === 'object' && v !== null) return deepRenameKey(oldKey, newKey, v); - return v; -} -/** Immutable. Functions in the object are not supported */ - - -function deepRenameKey(oldKey, newKey, obj) { - const newObj = {}; - - for (const [k, v] of Object.entries(obj)) newObj[k === oldKey ? newKey : k] = deepRenameValue(oldKey, newKey, v); - - return newObj; -} -/** Mutable (changes the `obj` object) */ - - -function deepRenameKey_(oldKey, newKey, obj) { - const stack = []; - stack.push(obj); - - while (stack.length !== 0) { - const obj = stack.pop(); - - if (oldKey in obj && !Array.isArray(obj)) { - obj[newKey] = obj[oldKey]; - delete obj[oldKey]; - } - - for (const v of Object.values(obj)) { - if (typeof v === 'object' && v !== null) // `v` is read-only here, but we want to mutate it - // $FlowIgnore[incompatible-call] - stack.push(v); - } - } - - return obj; -} \ No newline at end of file diff --git a/tdlib/tdl/uuidv4.js b/tdlib/tdl/uuidv4.js deleted file mode 100644 index aeda0b1..0000000 --- a/tdlib/tdl/uuidv4.js +++ /dev/null @@ -1,30 +0,0 @@ -// @flow -/* eslint-disable */ - -const charset = '0123456789abcdef'.split(''); -const randomset = new Uint8Array(16); - -function uuid()/*: string */ { - let rand = 0; - for (let i = 0; i < 16; i++) { - if (rand < 2) { - rand += Math.random() * (1 << 24); - } - randomset[i] = rand & 0xFF; - rand >>>= 8; - } - - randomset[6] = (randomset[6] & 0x0F) | 0x40; - randomset[8] = (randomset[8] & 0x3F) | 0x80; - - let output = ''; - for (let i = 0; i < 16; i++) { - const rnd = randomset[i]; - output += charset[rnd & 15]; - output += charset[rnd >>> 4]; - } - - return output; -} - -module.exports = uuid diff --git a/tdlib/tdlib.js b/tdlib/tdlib.js deleted file mode 100644 index ac1d7d6..0000000 --- a/tdlib/tdlib.js +++ /dev/null @@ -1,88 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.TDLib = void 0; - -var _debug = _interopRequireDefault(require("debug")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -let debug = (0, _debug.default)('tdl-tdlib-addon'); -// debug = ()=>{} - -const defaultLibraryFile = (() => { - switch (process.platform) { - case 'win32': - return 'tdjson.dll'; - - case 'darwin': - return 'libtdjson.dylib'; - - default: - return 'libtdjson.so'; - } -})(); - -class TDLib { - constructor(libraryFile = defaultLibraryFile, addonPath = './td.node') { - _defineProperty(this, "_addon", void 0); - - debug('constructor'); // $FlowIgnore[unsupported-syntax] - - this._addon = require(addonPath); // console.log(this._addon) - - this._addon.load_tdjson(libraryFile); - } - - getName() { - return 'addon'; - } - - create() { - debug('create'); - return this._addon.td_client_create(); - } - - send(client, query) { - this._addon.td_client_send(client, JSON.stringify(query)); - } // async receive (client: TDLibClient, timeout: number): Promise { - // const res = await this._addon.td_client_receive(client, timeout) - // if (!res) return null - // return JSON.parse(res) - // } - - - receive(client, timeout) { - return new Promise((resolve, reject) => { - this._addon.td_client_receive(client, timeout, (err, res) => { - if (err) return reject(err); - if (!res) return resolve(null); - resolve(JSON.parse(res)); - }); - }); - } - - execute(client, query) { - const res = this._addon.td_client_execute(client, JSON.stringify(query)); - - if (!res) return null; - return JSON.parse(res); - } - - destroy(client) { - debug('destroy'); - - this._addon.td_client_destroy(client); - } - - setLogFatalErrorCallback(fn) { - this._addon.td_set_fatal_error_callback(fn); - } - -} - -exports.TDLib = TDLib; \ No newline at end of file