Coder Social home page Coder Social logo

bannerets / tdl Goto Github PK

View Code? Open in Web Editor NEW
352.0 10.0 48.0 4.12 MB

Node.js bindings to TDLib ๐Ÿฅ’

Home Page: https://git.io/tdl

License: MIT License

JavaScript 78.58% Shell 0.23% Python 1.01% C++ 17.22% TypeScript 2.96%
telegram tdlib tglib telegram-api tdjson libtdjson wrapper td node-addon bindings

tdl's Introduction

tdl ย  npm CI

tdl is a fairly simple JavaScript wrapper for TDLib (Telegram Database library), a library to create Telegram clients or bots.

TDLib version 1.5.0 or newer is required.

Requirements

  • Node.js v12.11.0 or newer (>= v16 recommended)
  • The tdjson shared library (libtdjson.so on Linux, libtdjson.dylib on macOS, tdjson.dll on Windows)
  • In some cases, a C++ compiler and Python installed to build the node addon1

Installation

  1. Build TDLib (https://github.com/tdlib/td#building) or install pre-built libraries
  2. Run npm install tdl
  3. (optional) If you use TypeScript, types for TDLib are installed separately, see the Types section

To use tdl, you need to get TDLib first. The tdjson shared library should be present in the system search paths (otherwise the path to libtdjson can be specified manually).

Tip: When building TDLib, the libraries can be installed into the system using cmake --install . (optionally specify the --prefix option, the default is /usr/local) after TDLib has been built successfully. This command may require sudo.

prebuilt-tdlib

Instead of building TDLib from source, you can possibly install pre-built TDLib libraries distributed through the prebuilt-tdlib npm package (npm install prebult-tdlib). To install prebuilt-tdlib for a specific TDLib version, for example v1.8.26, run npm install [email protected]. The available versions of prebuilt-tdlib can be found by running npm info prebuilt-tdlib dist-tags. An example of using libraries from prebuilt-tdlib is present in the section below. The supported systems are x86_64 GNU/Linux, x86_64 & arm64 macOS, and x86_64 Windows. See the README of prebuilt-tdlib for additional information.

Getting started

const tdl = require('tdl')

// If libtdjson is not present in the system search paths, the path to the
// libtdjson shared library can be set manually, e.g.:
//   tdl.configure({ tdjson: '/usr/local/lib/libtdjson.dylib' })
// The library directory can be set separate from the library name,
// example to search for libtdjson in the directory of the current script:
//   tdl.configure({ libdir: __dirname })

// Instead of building TDLib yourself, the aforementioned prebuilt-tdlib can be used as follows:
//   const { getTdjson } = require('prebuilt-tdlib')
//   tdl.configure({ tdjson: getTdjson() })

const client = tdl.createClient({
  apiId: 2222, // Your api_id
  apiHash: '0123456789abcdef0123456789abcdef' // Your api_hash
})
// Passing apiId and apiHash is mandatory,
// these values can be obtained at https://my.telegram.org/

client.on('error', console.error)

// Aside of receiving responses to your requests, the server can push to you
// events called "updates" which ar received as follows:
client.on('update', update => {
  console.log('Got update:', update)
})

async function main () {
  // Log in to a Telegram account. By default, with no arguments, this function will
  // ask for phone number etc. in the console. Instead of logging in as a user,
  // it's also possible to log in as a bot using `client.loginAsBot('<TOKEN>')`.
  await client.login()

  // Invoke a TDLib method. The information regarding TDLib method list and
  // documentation is below this code block.
  const me = await client.invoke({ _: 'getMe' })
  console.log('My user:', me)

  // Invoke some other TDLib method.
  const chats = await client.invoke({
    _: 'getChats',
    chat_list: { _: 'chatListMain' },
    limit: 10
  })
  console.log('A part of my chat list:', chats)

  // Close the instance so that TDLib exits gracefully and the JS runtime can finish the process.
  await client.close()
}

main().catch(console.error)

The API list of TDLib methods, which are called using client.invoke, can be found at, e.g.:

In the TDLib documentation, the bytes type means a base64-encoded string. int64 accepts either a number or a string, pass string for large numbers. int32, int53, and double are the number JS type.

If TypeScript types for TDLib are installed, note the types are annotated with jsdoc comments, and the documentation can also be browsed directly in the .d.ts file or in the autocompletion menu of the editor.

See also https://core.telegram.org/tdlib/getting-started for some basic information on how to use TDLib (tdl handles the authorization part with client.login). Note that the TDLib JSON interface actually sends a @type field, but tdl renames it to _.

Some short examples are available in the examples/ directory.

API

Note: A more exhaustive documentation is available in the TypeScript typings file.

tdl.configure(options: TDLibConfiguration) => void

Configure several parameters such as libtdjson name or verbosity level. This function should be called before tdl.createClient or tdl.execute.

tdl.configure({
  // Path to the library. By default, it is 'tdjson.dll' on Windows,
  // 'libtdjson.dylib' on macOS, or 'libtdjson.so' otherwise.
  tdjson: 'libtdjson.so',
  // Path to the library directory. By default, it is empty string.
  libdir: '/usr/local/lib',
  // Verbosity level of TDLib. By default, it is 2.
  verbosityLevel: 3,
  // Experimental option. Disabled by default.
  useNewTdjsonInterface: false
})

Some examples:

  • tdl.configure({ tdjson: '/root/libtdjson.so', verbosityLevel: 5 })
  • tdl.configure({ tdjson: 'libtdjson.dylib.1.8.6', libdir: '/usr/local/lib' })
  • tdl.configure({ libdir: __dirname })
  • tdl.configure({ tdjson: require('prebuilt-tdlib').getTdjson() })

The path concatenation of libdir + tdjson is directly passed to dlopen (Unix) or LoadLibrary (Windows). Check your OS documentation to find out where the shared library will be searched for.

tdl.createClient(options: ClientOptions) => Client

Create a TDLib client.

const client = tdl.createClient({
  apiId: 2222, // Your api_id
  apiHash: '0123456789abcdef0123456789abcdef' // Your api_hash
  // ... other options ...
})

The options that can be passed here have the following interface:

type ClientOptions = {
  apiId: number, // Can be obtained at https://my.telegram.org
  apiHash: string, // Can be obtained at https://my.telegram.org
  databaseDirectory: string, // Relative path (defaults to '_td_database')
  filesDirectory: string, // Relative path (defaults to '_td_files')
  databaseEncryptionKey: string, // Optional key for database encryption
  useTestDc: boolean, // Use test telegram server (defaults to false)
  tdlibParameters: Object, // Raw TDLib parameters
  // Advanced options:
  bare: boolean,
  skipOldUpdates: boolean
}

Of these fields, only apiId and apiHash are required. Any other field can be omitted. They are more thoroughly described in the documentation comments of TypeScript types.

The tdlibParameters option is described in https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1tdlib_parameters.html.

By default, in tdl, tdlibParameters is set to:

tdlibParameters: {
  use_message_database: true,
  use_secret_chats: false,
  system_language_code: 'en',
  application_version: '1.0',
  device_model: 'Unknown device',
  system_version: 'Unknown',
  api_id: options.apiId,
  api_hash: options.apiHash,
  database_directory: options.databaseDirectory,
  files_directory: options.filesDirectory,
  use_test_dc: options.useTestDc
}

In a real application, you probably want to change device_model and other parameters.

client.login(fn?: () => LoginDetails) => Promise<void>

Log in to your Telegram account.

await client.login()

By default, tdl asks the user for the phone number, auth code, and 2FA password (if needed) in the console. You can override the defaults with custom functions, for example:

// Example
await client.login(() => ({
  getPhoneNumber: retry => retry
    ? Promise.reject('Invalid phone number')
    : Promise.resolve('+9996620001'),
  getAuthCode: retry => retry
    ? Promise.reject('Invalid auth code')
    : Promise.resolve('22222'),
  getPassword: (passwordHint, retry) => retry
    ? Promise.reject('Invalid password')
    : Promise.resolve('abcdef'),
  getName: () => Promise.resolve({ firstName: 'John', lastName: 'Doe' })
}))

The getName function is called if the user is not signed up.

client.login supports only a subset of authentication methods available on Telegram. It is possible (and advisable for larger apps) not to use the client.login helper and implement the authorization process manually, handling authorizationStateWaitPhoneNumber and other updates.

This function accepts the following interface:

type LoginDetails = {
  type?: 'user',
  getPhoneNumber?: (retry?: boolean) => Promise<string>,
  getEmailAddress?: () => Promise<string>,
  getEmailCode?: () => Promise<string>,
  confirmOnAnotherDevice?: (link: string) => void,
  getAuthCode?: (retry?: boolean) => Promise<string>,
  getPassword?: (passwordHint: string, retry?: boolean) => Promise<string>,
  getName?: () => Promise<{ firstName: string, lastName?: string }>
} | {
  type: 'bot',
  getToken: (retry?: boolean) => Promise<string>
}
// Note that client.login accepts a function that returns the object, not the
// object directly. The function will not be called if the client is already
// authorized.
declare function login (fn?: () => LoginDetails): Promise<void>

getEmailAddress and getEmailCode are called in TDLib >= v1.8.6 only.

client.loginAsBot(token: string | (() => string | Promise<string>)) => Promise<void>

Instead of logging in as a user, you can log in as a bot using a bot token.

await client.loginAsBot('YOUR_BOT_TOKEN') // Enter your token from @BotFather

client.on(event: string, callback: Function) => Client

Attach an event listener to receive updates and other events.

function onUpdate (update) {
  console.log('New update:', update)
}
client.on('update', onUpdate)
client.on('error', console.error)

Ideally, you should always have a listener on client.on('error'). There is no default listener, all errors will be ignored otherwise.

You can consider using reactive libraries like RxJS or most.js for convenient event processing.

Some other rarely-used events also exist and are described in the TypeScript interface.

client.addListener is an alias for client.on.

client.once(event: string, callback: Function) => Client

Attach a one-time listener.

client.off(event: string, listener: Function, once?: boolean) => Client

Remove an event listener.

const listener = u => {
  console.log('New update:', u)
  if (u?.authorization_state?._ === 'authorizationStateReady')
    client.off('update', listener) // Removes the listener
}
client.on('update', listener)

client.removeListener is an alias for client.off.

client.invoke(query: Object) => Promise<Object>

Call a TDLib method asynchronously. The promise can be rejected with a TDLib object of type _: 'error'.

For the information regarding TDLib API list, see the "Getting started" section of this README.

const chats = await client.invoke({
  _: 'getChats',
  chat_list: { _: 'chatListMain' },
  limit: 4000
})
await client.invoke({
  _: 'sendMessage',
  chat_id: 123456789,
  input_message_content: {
    _: 'inputMessageText',
    text: {
      _: 'formattedText',
      text: '๐Ÿ‘ป'
    }
  }
})

client.close() => Promise<void>

Close the TDLib client.

await client.close()

tdl.execute(query: Object) => (Object | null)

Call a TDLib method synchronously. This function can be used only with the methods marked as "can be called synchronously" in the TDLib documentation.

const res = tdl.execute({
  _: 'getTextEntities',
  text: '@telegram /test_command https://telegram.org telegram.me'
})

client.execute is the same as tdl.execute.

tdl.setLogMessageCallback(maxVerbosityLevel: number, cb: Function | null) => void

Set the callback that is called when a message is added to the TDLib log. This corresponds to the td_set_log_message_callback tdjson function. The callback overrides previously set callbacks.

Types

Tip: It is considerably more convenient to use tdl with TypeScript, which enables full autocompletion for the TDLib methods and objects along with the documentation.

While tdl works with any TDLib version (above the requirement), the TypeScript types have to be installed specifically for the TDLib version you use. This can be done via a small tdl-install-types utility, which downloads and generates types for you. It can be called using npx tdl-install-types without any separate installation.

$ npx tdl-install-types [<options>] [<target>]

(Type "y" in case it asks to install the tdl-install-types package.)

The utility can generate types given a tdjson library file (e.g. npx tdl-install-types ./libtdjson.so), a TDLib git ref (examples: npx tdl-install-types v1.8.0, npx tdl-install-types master, npx tdl-install-types 2de39ffffe71dc41c538e66085658d21cecbae08), or a td_api.tl file (npx tdl-install-types td_api.tl). When called without arguments, it will try to use require('prebuilt-tdlib').getTdjson() as the tdjson library, generating types for the installed version of prebuilt-tdlib.

By default, the types are generated into a tdlib-types.d.ts file that you can git-commit. The declaration file should be inside your project to work. When you update the version of TDLib, don't forget to also update the types: it's important to keep the types in sync with the interface TDLib actually uses.

$ # Various examples:
$ npx tdl-install-types libtdjson.so # generate types for this shared library in the cwd
$ npx tdl-install-types 0ada45c3618108a62806ce7d9ab435a18dac1aab # types for the TDLib commit
$ npx tdl-install-types # tries to use prebult-tdlib
$ npx tdl-install-types v1.8.0 # types for the git tag in the TDLib repository

See npx tdl-install-types --help for additional information.

The types can be imported by using the tdlib-types module name:

import type * as Td from 'tdlib-types'
// And use as: Td.message, Td.user, ...

That is, a package named tdlib-types does not need to be installed separately.

Note that when using npx, the version of tdl-install-types might be cached and outdated if you are not appending the @latest tag (npx tdl-install-types@latest --help). You can also install the utility globally or per-project as a dev dependency.

If you encounter any issues, create a new issue in the tdl's GitHub tracker.

Other JavaScript runtimes

Since bun is Node.js-compatible and supports Node-API, tdl should work out of the box, however the stability may not be the best yet.

deno can also import tdl through the node compatibility via import * as tdl from 'npm:tdl'. Currently, the Node-API implementation in deno is incorrect and race conditions leading to random segfaults sometimes occur. Not recommended to use tdl in deno.

tdl depends on native libraries and cannot be used in the browser. However, TDLib itself can possibly work in the browser by compiling it to WebAssembly. There is an outdated official tdweb library, for example. Previously, tdl implemented basic browser support as well, but the idea has been dropped.

Possible errors

  • Dynamic Loading Error: Win32 error 126 (Windows)
  • Dynamic Loading Error: dlopen(โ€ฆ) image not found (macOS)
  • โ€ฆcannot open shared object file: No such file or directory (Linux)

The tdjson shared library or one of its dependencies (for example, libssl) cannot be found. To troubleshoot dependency issues, try to run ldd libtdjson.so on Linux or otool -L libtdjson.dylib on macOS. On Windows, you can use an app like Dependency Walker.

Recheck the documentation of dlopen (Linux), dlopen (macOS), Dynamic-Link Library Search Order (Windows) to make sure the shared library is present in the search paths. By default, Linux does not search in the current working directory, while macOS does.

  • fatal error: napi.h: no such file or directory
  • error: no such file or directory: โ€ฆ/node-modules/node-addon-api

The path to the directory where you execute npm install likely contains spaces, which is not supported by gyp: nodejs/node-gyp#65 (comment).

  • UPDATE_APP_TO_LOGIN

Update TDLib to v1.7.9 (v1.8.0) or newer. It is no longer possible to log in by phone number in older versions of TDLib.

  • Error while reading RSA public key

You can get this error if libtdjson is dynamically linked against OpenSSL and some of the symbols got resolved into Node.js instead of the system OpenSSL.

Note that Node.js also uses OpenSSL (the distributed binaries are statically linked against it) and exports the OpenSSL symbols. In the result, there are two versions of OpenSSL in the same application. Then, using standard dlopen, especially on Linux, most of the symbols will be resolved into libcrypto inside the Node.js binary, not into the system libcrypto. It still can work correctly if the versions are ABI-compatible, i.e. if TDLib is linked against an OpenSSL version sufficiently similar to the version that Node.js uses (node -p "process.versions.openssl").

tdl tries to get around the symbol conflict issues by using RTLD_DEEPBIND when available, so these issues should be rare in practice (unless you use musl).

You can use lldb or gdb to check whether the symbols get resolved into Node.js. For example, open lldb -- node index.js and set these breakpoints:

break set -r EVP_ -s node
break set -r AES_ -s node
break set -r BIO_ -s node
break set -r RSA_ -s node
break set -r CRYPTO_ -s node

It's also possible to set breakpoints inside the system OpenSSL:

break set -r . -s libcrypto.so.1.1
break set -r . -s libssl.so.1.1

To solve this issue, try to link TDLib statically against OpenSSL (the OPENSSL_USE_STATIC_LIBS option in cmake) or link it against the OpenSSL version that Node.js uses.

Another possible option is to rebuild Node.js from source, linking it dynamically against the same system OpenSSL. That way, there is only one instance of OpenSSL in the application. For example, using nvm, you can install Node.js v16 from source on GNU/Linux via this command:

$ nvm install -s 16 --shared-openssl --shared-openssl-includes=/usr/include/ --shared-openssl-libpath=/usr/lib/x86_64-linux-gnu/

However, it's inconvenient for most users to rebuild Node.js.

Another hypothetical solution is to rebuild TDLib with the OpenSSL headers distributed in Node.js (<path-to-node>/include/node/) without linking it to anything, simply leaving the undefined symbols. Using this option, there is also only one OpenSSL. I haven't checked that this works or that Node exports all the symbols needed for TDLib. With this option, TDLib also should be rebuilt every time Node.js updates the OpenSSL dependency.

This issue doesn't apply to Electron because it doesn't export the OpenSSL symbols.

  • Segmentation fault

The cause of the segfault might be the same as above. If you get segmentation faults, open an issue.

Footnotes

  1. tdl is packaged with pre-built addons for Windows (x86_64), GNU/Linux (x86_64; glibc >= 2.17), and macOS (x86_64, aarch64; v10.14+). If a pre-built binary is not available for your system, then the node addon will be built using node-gyp, requiring Python and a C++ toolchain (C++14 is required) to be installed (on Windows, MSVS or Build Tools). Pass --build-from-source to never use the pre-built binaries. Note that macOS aarch64 binaries aren't tested. โ†ฉ

tdl's People

Contributors

bannerets avatar ilyasemenov avatar laptou avatar mikkelvp avatar nodegin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tdl's Issues

Promise is not rejected

When I run following code

tdClient.invoke({
    _: 'downloadFile',
    file_id: 1,
    priority: 1,
});

And telegram returns error , tdl is not reject the promise

I have this warning from tdlib

[ 2][t 4][1531228492.951207876][FileManager.cpp:2251][!FileManager] Failed to upload/download/generate file: [Error : 400 : LOCATION_INVALID]. Query type = 2. File type is documents

My code blockes in promise because it is not resolved/rejected
https://github.com/tdlib/td/blob/master/td/telegram/files/FileManager.cpp#L2251

Does not work in Electron on Windows

Despite my best efforts, I cannot get this to work in Electron. The program always fails and shows an error window indicating a C/C++ error, not even a JS error:

image

My steps:

  1. Create an empty Node.js project.
  2. Install electron, tdl, and electron-rebuild.
  3. Run npx electron-rebuild to retarget the native bindings to Electron.
  4. Download the precompiled Telegram binaries and put them in a lib folder.
  5. Create index.js with the following code:
const { Client: TGClient } = require("tdl");

(async () => {
    console.log("initialising tg client");

    try {
        const tgClient = new TGClient({
            apiId: 000000,
            apiHash: "oops",
            binaryPath: "lib/tdjson",
            useTestDc: true,
            useMutableRename: true,
            verbosityLevel: 10
        });

        console.log("initialised tg client");

        await tgClient.connect();

        console.log("connected tg client");

        tgClient.on("update", (...args) => console.log("tg client: ", ...args));
        tgClient.on("error", (...args) => console.error("tg client: ", ...args));

    } catch (e) {
        console.error(e);
    }
})();
  1. Run npx electron . to launch the program.
  2. Program prints "initialised tg client", indicating that tdl successfully loads, but then crashes as soon as I call connect().
  3. Get confronted with this inscrutable error window.

Segmentation fault

Hi @Bannerets

I found that you have a similar project and I can see more details with verbositiyLevel: 10 with your lib
Any idea what is going wrong?
Thanks

[ 3][t 1][1527994939.187509060][Td.cpp:4633][!Td][&td_requests] Sending update: updateAuthorizationState {
authorization_state = authorizationStateWaitTdlibParameters {
}
}

[ 7][t 1][1527994939.192461252][Td.cpp:4771][!Td][&td_init] Begin to set TDLib parameters
[ 7][t 1][1527994939.192550898][Td.cpp:4796][!Td][&td_init] Fix parameters...
[ 7][t 1][1527994939.192634106][Td.cpp:4723][!Td][&td_init] Fix use_chat_info_db
[ 7][t 1][1527994939.192690134][Td.cpp:4727][!Td][&td_init] Fix use_file_db
[ 7][t 1][1527994939.192772150][Td.cpp:4798][!Td][&td_init] Check binlog encryption...
[ 3][t 1][1527994939.192883968][Binlog.cpp:340][!Td] Load: init encryption
[ 7][t 1][1527994939.192950010][Td.cpp:4802][!Td][&td_init] Init alarm multitimeout...
[ 7][t 1][1527994939.192986965][Td.cpp:4806][!Td][&td_init] Create Global
[ 7][t 1][1527994939.193028212][Td.cpp:4811][!Td][&td_init] Create MtprotoHeader
[ 7][t 1][1527994939.193070173][Td.cpp:4837][!Td][&td_init] Send authorizationStateWaitEncryptionKey
[ 7][t 1][1527994939.193114996][Td.cpp:4841][!Td][&td_init] Finish set parameters
[ 3][t 1][1527994939.193159103][Td.cpp:4633][!Td][&td_requests] Sending update: updateAuthorizationState {
authorization_state = authorizationStateWaitEncryptionKey {
is_encrypted = true
}
}

[ 3][t 1][1527994939.195223093][Td.cpp:4648][!Td][&td_requests] Sending result for request 1: ok {
}

[ 7][t 1][1527994939.198026180][Td.cpp:4413][!Td][&td_init] Begin to init database
[ 3][t 1][1527994939.198328257][Binlog.cpp:340][!Td] Load: init encryption
[ 4][t 1][1527994939.198956013][SqliteDb.cpp:177][!Td] ENCRYPT
Segmentation fault

Failed to parse

Hi,
When I ัall method getContacts I have this error:

[ 1][t 0][1538770932.840765238][ClientJson.cpp:76][&status.is_error()]Failed to parse [request{\0042@type\0042:\0042getContacts\0042,\0042@extra\0042:\00427597a042f9f94435a90bcd20e19a6c7e\0042}] [Error : 0 : Unknown class]

I call this method like this:
await client.invoke({ _: "getContacts" })

How to send code and pre text?

Formatted text to be sent; 1-GetOption("message_text_length_max") characters. Only Bold, Italic, Code, Pre, PreCode and TextUrl entities are allowed to be specified manually.

Please write an example of sending a message with bold text, pre and code.

json validator return error when login

when i login in a number it's return json validation error and app crash , error is some thing like below :


!!e SyntaxError: Unexpected token  in JSON at position 0
    at JSON.parse (<anonymous>)
    at _tdlib.td_json_client_receive.async (/tdlib/node_modules/tdl/dist/tdlib-ffi.js:80:24)
    at Object.<anonymous> (tdlib/node_modules/ffi-napi/lib/_foreign_function.js:115:9)

ENOENT: no such file or directory, open 'libtdjson.so'

I have the Nodejs app working in Local.
When I tried to install it in an AWS EC2 instance with Ubuntu 18.0.4 this error appears and the app crashes.

TDLib has been succesfully build and installed in /usr/local/lib/libtdjson.so so I cannot figure what's going wrong...

The code to instanciate TDLib:

    tdlib = new TDLib();
    client = new Client(tdlib, {
        apiId: process.env.TELEGRAM_API_ID,
        apiHash: process.env.TELEGRAM_API_HASH
    });

    await client.connectAndLogin();

And the output error:

{ Error: ENOENT: no such file or directory, open 'libtdjson.so'
at Object.openSync (fs.js:448:3)
at readFileSync (fs.js:348:35)
at new DynamicLibrary (/home/ubuntu/teletipsters/node_modules/ffi-napi/lib/dynamic_library.js:67:23)
at Object.Library (/home/ubuntu/teletipsters/node_modules/ffi-napi/lib/library.js:45:14)
at new TDLib (/home/ubuntu/teletipsters/node_modules/tdl-tdlib-ffi/dist/index.js:36:36)
at Object.tgClient.initialize (/home/ubuntu/teletipsters/services/tgClient.js:142:13)
at main (/home/ubuntu/teletipsters/index.js:15:24)
at Object. (/home/ubuntu/teletipsters/index.js:24:1)
at Module._compile (internal/modules/cjs/loader.js:816:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:827:10)
at Module.load (internal/modules/cjs/loader.js:685:32)
at Function.Module._load (internal/modules/cjs/loader.js:620:12)
at Function.Module.runMain (internal/modules/cjs/loader.js:877:12)
at internal/main/run_main_module.js:21:11
errno: -2,
syscall: 'open',
code: 'ENOENT',
path: 'libtdjson.so' }

Could you give me some help @Bannerets ?

Throwing error in input handler generates unhandled promise rejection

Steps to reproduce

const client = new Client({
	apiId: config.api_id,
	apiHash: config.api_hash,
	loginDetails: {
		phoneNumber: phone,
		getAuthCode: async () => {
			throw new Error("No interactive input available.")
		}
	}
})
client.on('update', console.log)
client.on('error', console.error)
await client.connect().catch(console.error)

Expected result

The error is passed to either the catch handler or to .on('error') handler.

Actual result

(node:45568) UnhandledPromiseRejectionWarning: Error: No interactive input available.
    at Object.getAuthCode (.../src/tg_client/index.ts:33:19)
    at Client._handleAuth (.../node_modules/tdl/dist/Client.js:267:43)
    at Client._handleUpdate (.../node_modules/tdl/dist/Client.js:218:21)
    at Client._handleResponse (.../node_modules/tdl/dist/Client.js:211:18)
    at Client._loop (.../node_modules/tdl/dist/Client.js:192:16)
(node:45885) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:45885) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Reasons / Proposed fix

Here:

this._loop()

you can see that _loop is called asynchronously, whatever exceptions happen inside will not be handled. As the warning says, this is not future proof (and of course doesn't allow to handle errors).

Also, I can see that _loop itself calls this._loop() asynchronously so I guess the problem will arise in other circumstances as well.

Error: ENOENT: no such file or directory, open '/app/libtdjson.so'

Locally it works.
But on server - not.

I have file on server:
./app/libtdjson.dylib

In the code I do this:

client = new Client({
  apiId: api_id,
  apiHash: hash,
  loginDetails: {
    type: 'user',
    phoneNumber: '+xxxxxxxxxx'
  }
});

2018-08-29T03:28:34.971644+00:00 app[web.1]: Auth error { Error: ENOENT: no such file or directory, open '/app/libtdjson.so'
2018-08-29T03:28:34.971647+00:00 app[web.1]: at Object.openSync (fs.js:434:3)
2018-08-29T03:28:34.971649+00:00 app[web.1]: at readFileSync (fs.js:339:35)
2018-08-29T03:28:34.971660+00:00 app[web.1]: at new DynamicLibrary (/app/node_modules/ffi-napi/lib/dynamic_library.js:67:23)
2018-08-29T03:28:34.971662+00:00 app[web.1]: at Object.Library (/app/node_modules/ffi-napi/lib/library.js:45:14)
2018-08-29T03:28:34.971668+00:00 app[web.1]: at new TDLib (/app/node_modules/tdl/dist/TDLib.js:38:37)
2018-08-29T03:28:34.971669+00:00 app[web.1]: at new Client (/app/node_modules/tdl/dist/Client.js:165:50)
2018-08-29T03:28:34.971671+00:00 app[web.1]: at Object. (/app/dist/telegram/channel-history/tg-with-tdlib/tg.js:357:26)
2018-08-29T03:28:34.971673+00:00 app[web.1]: at step (/app/dist/telegram/channel-history/tg-with-tdlib/tg.js:32:23)
2018-08-29T03:28:34.971674+00:00 app[web.1]: at Object.next (/app/dist/telegram/channel-history/tg-with-tdlib/tg.js:13:53)
2018-08-29T03:28:34.971676+00:00 app[web.1]: at /app/dist/telegram/channel-history/tg-with-tdlib/tg.js:7:71
2018-08-29T03:28:34.971678+00:00 app[web.1]: at new Promise ()
2018-08-29T03:28:34.971679+00:00 app[web.1]: at __awaiter (/app/dist/telegram/channel-history/tg-with-tdlib/tg.js:3:12)
2018-08-29T03:28:34.971685+00:00 app[web.1]: at Object.exports.parseSignalsFromChannels2 (/app/dist/telegram/channel-history/tg-with-tdlib/tg.js:337:58)
2018-08-29T03:28:34.971687+00:00 app[web.1]: at /app/dist/index.js:137:26
2018-08-29T03:28:34.971689+00:00 app[web.1]: at step (/app/dist/index.js:32:23)
2018-08-29T03:28:34.971691+00:00 app[web.1]: at Object.next (/app/dist/index.js:13:53)
2018-08-29T03:28:34.971693+00:00 app[web.1]: at /app/dist/index.js:7:71
2018-08-29T03:28:34.971695+00:00 app[web.1]: at new Promise ()
2018-08-29T03:28:34.971696+00:00 app[web.1]: at __awaiter (/app/dist/index.js:3:12)
2018-08-29T03:28:34.971698+00:00 app[web.1]: at init (/app/dist/index.js:133:12)
2018-08-29T03:28:34.971699+00:00 app[web.1]: at Object. (/app/dist/index.js:176:1)
2018-08-29T03:28:34.971701+00:00 app[web.1]: at Module._compile (internal/modules/cjs/loader.js:689:30)
2018-08-29T03:28:34.971703+00:00 app[web.1]: errno: -2,
2018-08-29T03:28:34.971704+00:00 app[web.1]: syscall: 'open',
2018-08-29T03:28:34.971706+00:00 app[web.1]: code: 'ENOENT',
2018-08-29T03:28:34.971708+00:00 app[web.1]: path: '/app/libtdjson.so' }

@Bannerets
What I missed?

How to get chats with unread messages

Hi!
In my app, after it's started, i need to know which unread messages (and from whom) i have.so i need some way to easily gather this information, and also mark messages as read after my app processes them.what API calls should i use to achieve this?

deepRenameKey on arrays

When send queries which contains arrays, deepRenameKeys converts indexes as keys of object and returns object instead of array.

Example - here

GetChatHistoryRequest error "Invalid local location: WindowsError: The system cannot find the specified file"

When I loop getChatHistory a few times, I get a few errors sometimes. They don't crash anything, but I don't know where they come from. I'm not telling the program to open any file. I'm just getting text versions of the history. Why is it erroring out while trying to find a file?

The part in Spanish says WindowsError: The system cannot find the specified file

[ 2][t 4][1539727854.579417129][filemanager.cpp:722][!GetChatHistoryRequest]
Invalid local location: [WindowsError : El sistema no puede encontrar el archivo especificado.
: 2 : File "C:\Users\pc\projects\electrogram\_td_files\photos\806007111_124372.jpg" can't be
opened for reading] from load_from_pmc
[ 2][t 4][1539717855.600638105][filemanager.cpp:722][!GetChatHistoryRequest]
Invalid local location: [WindowsError : El sistema no puede encontrar el archivo especificado.
: 2 : File "C:\Users\pc\projects\electrogram\_td_files\photos\806018502_97443.jpg" can't be
opened for reading] from load_from_pmc
[ 2][t 4][1538727855.601184207][filemanager.cpp:722][!GetChatHistoryRequest]
Invalid local location: [WindowsError : El sistema no puede encontrar el archivo especificado. 
: 2 : File "C:\Users\pc\projects\electrogram\_td_files\photos\806021027_102722.jpg" can't be
opened for reading] from load_from_pmc

edit: This is my code:

const getChatHistory = (chat_id, from_message_id, offset, limit, only_local = false) =>
  client.invoke({ _: 'getChatHistory', chat_id, from_message_id, offset, limit, only_local })

const insertHistory = (chat_id, lastID = 0) =>
  getChatHistory(chat_id, lastID, 0, 100).then(res =>
    res.messages
      && res.messages.length
      && messages.insert(res.messages).then(() =>
          insertHistory(chat_id, log(res.messages[res.messages.length -1].id))))

Client does not support session resuming which leads to a state when the client is unable to authenticate

Steps to reproduce:

  1. write a simple script that connects and calls login()
  2. run the script
  3. wait until Enter Code prompt is displayed
  4. break with Ctrl+C
  5. start the script again immediately

What happens:
No prompt is displayed.

What should happen
Enter Code prompt should appear or at least an event for resuming a session should be generated.

Analysis:
It seems that the default behavior of TDL library (.so) is to resume previous session when stopped in the middle of authentication. The client (nodejs) does not implement this flow at all and get stuck without ability to do authentication properly.
The problem is that immediately after connect() is called, an event authorizationStateWaitCode is generated. This happens even without calling login(). The Client does not expect this. Calling login will cause indefinite waiting for authorizationStateWaitPhoneNumber which will never happen (TDL already knows the phone number from previous script run).

Suggestion:
There must be a way to specify login/auth promises before calling login (in Options for example). In case when authorizationStateWaitCode appears before calling login, we can call getAuthCode() method specified by the user.

Segfault on connect

Tried running example from readme on my linux machine and received segfault when connect method was called.

node 10.4.1
tdl latest
tdlib 1.2.0

PID 15192 received SIGSEGV for address: 0x10
node(EVP_MD_CTX_clear_flags+0x6)[0x13734a6]
node(EVP_DigestInit_ex+0x1e)[0x135d3de]
node(HMAC_Init_ex+0x153)[0x137cb93]
/app/deps/td/build/libtdjson.so(+0x881c1b)[0x7f687f6f5c1b]
/app/deps/td/build/libtdjson.so(+0x88cc70)[0x7f687f700c70]
/app/deps/td/build/libtdjson.so(+0x8b37bd)[0x7f687f7277bd]
/app/deps/td/build/libtdjson.so(+0x8cf99f)[0x7f687f74399f]
/app/deps/td/build/libtdjson.so(+0x8dece0)[0x7f687f752ce0]
/app/deps/td/build/libtdjson.so(+0x8dee7f)[0x7f687f752e7f]
/app/deps/td/build/libtdjson.so(+0x8e3c67)[0x7f687f757c67]
/app/deps/td/build/libtdjson.so(+0x918fc1)[0x7f687f78cfc1]
/app/deps/td/build/libtdjson.so(+0x91a407)[0x7f687f78e407]
/app/deps/td/build/libtdjson.so(+0x91b6b2)[0x7f687f78f6b2]
/app/deps/td/build/libtdjson.so(+0x91b956)[0x7f687f78f956]
/app/deps/td/build/libtdjson.so(+0x9104d9)[0x7f687f7844d9]
/app/deps/td/build/libtdjson.so(+0x91a407)[0x7f687f78e407]
/app/deps/td/build/libtdjson.so(+0x90dc6a)[0x7f687f781c6a]
/app/deps/td/build/libtdjson.so(+0x8650bc)[0x7f687f6d90bc]
/app/deps/td/build/libtdjson.so(+0x867660)[0x7f687f6db660]
/app/deps/td/build/libtdjson.so(+0x29bcc0)[0x7f687f10fcc0]
/app/deps/td/build/libtdjson.so(+0x29d30b)[0x7f687f11130b]
/app/deps/td/build/libtdjson.so(+0x29dd31)[0x7f687f111d31]
/app/deps/td/build/libtdjson.so(+0x268bf7)[0x7f687f0dcbf7]
/app/deps/td/build/libtdjson.so(+0x26df3c)[0x7f687f0e1f3c]
/app/deps/td/build/libtdjson.so(+0x168cac)[0x7f687efdccac]
/app/deps/td/build/libtdjson.so(+0x871bef)[0x7f687f6e5bef]
/app/deps/td/build/libtdjson.so(+0x87616a)[0x7f687f6ea16a]
/app/deps/td/build/libtdjson.so(+0x8764d9)[0x7f687f6ea4d9]
/app/deps/td/build/libtdjson.so(+0x876c68)[0x7f687f6eac68]
/app/deps/td/build/libtdjson.so(+0x86ebf2)[0x7f687f6e2bf2]

Destroy bad sqlite

when i use tdl it's show below error
[ 1][t 3][1549696839.615714312][TdDb.cpp:381][!Td] Destroy bad sqlite db because of: [Error : 0 : [query:ATTACH DATABASE '/home/example/javascript/_td_database/db.sqlite.ecnrypted' AS encrypted KEY "x'06e1fbfd20d0755a4ff54e6b9bbffe27a4be52f0e11457a2b0130c0e6df95fee'"] failed: unable to open database: /home/example/javascript/_td_database/db.sqlite.ecnrypted]

graceful shutdown?

Is there anyway to gracefully shut down the instance? Current I just kill the press, but looking for some better solutions?

Napi::Error

I started 5 clients and immediately I'm seeing this error:

libc++abi.dylib: terminating with uncaught exception of type Napi::Error
Abort trap: 6

Any suggestions?

Providing precompiled TDLIB

Hi! I'm working on small project that needs to connect to telegram client api in order to create conversation. I tried mtproto lib, however its really buggy and looks unusable. This library works really well, but I don't want my users to be forced to manually compile tdlib. Can I somehow ship prebuilt TDLib and nodejs binaries in one executable file?

Thanks for awesome lib

Can't make it work after upgrade to ver. 6

running this script with provided ENV variables (verified that they are available through the console.log):

const { TDL } = require('tdl-tdlib-addon')
const { Client } = require('tdl-tdlib-addon');

console.log('Creating a client for: \n'+process.env.PHONE_NUMBER);
console.log('Creating a client for: \n'+process.env.API_KEY);

new TDL('./node_modules/tdl-tdlib-addon/build/Release/td.node');

const client = new Client({
  apiId: process.env.API_KEY,
  apiHash: process.env.API_HASH,
})

async function main() {
  await client.connect()
  await client.login(() => ({
    phoneNumber: process.env.PHONE_NUMBER
  }))

  const result = await client.invoke({
    _: 'getChats',
    offset_order: '9223372036854775807',
    offset_chat_id: 0,
    limit: 100
  })

  // latest 100 chats will be returned
  console.log(result)
}

main()

fails with this:
/Users/jeff/tf_new/node_modules/tdl/dist/client.js:243
if (!options.apiId) throw new TypeError('Valid api_id must be provided.');
^

TypeError: Valid api_id must be provided.
at new Client (/Users/jeff/tf_new/node_modules/tdl/dist/client.js:243:31)
at Object. (/Users/jeff/tf_new/index.js:7:1)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
at startup (internal/bootstrap/node.js:266:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:596:3)

Would appreciate the help.

Can't run due to "Dynamic Linking Error"

I just installed the library and I haven't been able to run it. This might be an installation problem. I followed the instructions to the letter.

My code is:

const { Client } = require('tdl')

const client = new Client({
  apiId: my.id, // Your api_id
  apiHash: my.hash// Your api_hash
})

This is the error I get:

C:\Users\pc\projects\denbot\node_modules\ffi-napi\lib\dynamic_library.js:74
    throw new Error('Dynamic Linking Error: ' + err);
    ^

Error: Dynamic Linking Error: Win32 error 126
    at new DynamicLibrary (C:\Users\pc\projects\denbot\node_modules\ffi-napi\lib\dynamic_library.js:74:11)
    at Object.Library (C:\Users\pc\projects\denbot\node_modules\ffi-napi\lib\library.js:45:14)
    at new TDLib (C:\Users\pc\projects\denbot\node_modules\tdl\dist\tdlib-ffi.js:42:37)
    at new Client (C:\Users\pc\projects\denbot\node_modules\tdl\dist\client.js:180:50)
    at Object.<anonymous> (C:\Users\pc\projects\denbot\index.js:3:16)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)

Attempts to remove the user from the group

Hi guys,
I'm trying to remove users from groups.
As I know, I need to use setChatMemberStatus with chatMemberStatusLeft
I do it like this:
await client.invoke({ _: 'setChatMemberStatus', chat_id: chat_id, user_id: user_id, status: { _: 'chatMemberStatusLeft' } })
but I have mistake:
[ 1][t 0][1539547507.848958015][ClientJson.cpp:71] Failed to parse [request:{\0042@type\0042:\0042setChatMemberStatus\0042,\0042chat_id\0042:{\0042@type\0042:\0042chat\0042,\0042id\0042:-243305143,\0042type\0042:{\0042@type\0042:\0042chatTypeBasicGroup\0042,\0042basic_group_id\0042:243305143},\0042title\0042:\0042week1\0042,\0042last_message\0042:{\0042@type\0042:\0042message\0042,\0042id\0042:7116685312,\0042sender_user_id\0042:416593229,\0042chat_id\0042:-243305143,\0042is_outgoing\0042:true,\0042can_be_edited\0042:false,\0042can_be_forwarded\0042:false,\0042can_be_deleted_only_for_self\0042:true,\0042can_be_deleted_for_all_users\0042:true,\0042is_channel_post\0042:false,\0042contains_unread_mention\0042:false,\0042date\0042:1539503305,\0042edit_date\0042:0,\0042reply_to_message_id\0042:0,\0042ttl\0042:0,\0042ttl_expires_in\0042:0,\0042via_bot_user_id\0042:0,\0042author_signature\0042:\0042\0042,\0042views\0042:0,\0042media_album_id\0042:\00420\0042,\0042content\0042:{\0042@type\0042:\0042messageChatAddMembers\0042,\0042member_user_ids\0042:[622108130]}},\0042order\0042:\00426612116347058920067\0042,\0042is_pinned\0042:false,\0042is_marked_as_unread\0042:false,\0042is_sponsored\0042:false,\0042can_be_reported\0042:false,\0042default_disable_notification\0042:false,\0042unread_count\0042:0,\0042last_read_inbox_message_id\0042:0,\0042last_read_outbox_message_id\0042:6362759168,\0042unread_mention_count\0042:0,\0042notification_settings\0042:{\0042@type\0042:\0042chatNotificationSettings\0042,\0042use_default_mute_for\0042:true,\0042mute_for\0042:0,\0042use_default_sound\0042:true,\0042sound\0042:\0042\0042,\0042use_default_show_preview\0042:true,\0042show_preview\0042:false},\0042reply_markup_message_id\0042:0,\0042client_data\0042:\0042\0042},\0042user_id\0042:622108130,\0042status\0042:{\0042@type\0042:\0042chatMemberStatusLeft\0042},\0042@extra\0042:\0042d8dd721525dd94cb3b5ba59c97bec26b\0042}] [Error : 0 : Expected String or Number, got Object]

Auto reconnect

How can I automatically reconnect when connection closed?

How to extract TD database data?

TDLib cashes some data to DB i.e. it saves external user's access hashes

And when we trying to call something that affect user_id i.e. getUserFullInfo we'll got "user not found" error if TDLib not saves user's access_hash before. It caches automatically when we resolving user by username or fetching group members where user participates.

Is it possible to extract that info from TDLib's DB?

How about helpers?

How about doing some useful helpers that you still need to implement when using the library

For example, I really need something like

saveFile(fileId, priority = 1, timeout = 10);
{
  return _client.invoke({
    _: 'downloadFile',
    file_id: fileId,
    priority,
  })
  .then(() => {
    return new Promise((resolve, reject) => {
      const downloadFinishListener = (e) => {
        if (e._ === 'updateFile')
          if (e.file.id === fileId) {
            _client.removeListener('update', downloadFinishListener);
            resolve(e.file);
          }
      };

      _client.on('update', downloadFinishListener);

      setTimeout(() => {
        _client.removeListener('update', downloadFinishListener);
        reject('Download timed out');
      }, timeout * 1000);
    });
  });
}

After entering login code nothing happens

Hello everyone!

When I try to login with my own phone number everything works fine. I receive code and after entering it an app fetches first 10 chats. When I try to use my friends phone, nothing happens after entering code. No error messages. What can be the problem?

Thanks in advance!

Error: Cannot read property 'sender_user_id' of undefined

After start login with:
await client.connect() await client.login(() => ({ phoneNumber: '79991111111' //my number }));

got error:
Got error: Error: Cannot read property 'sender_user_id' of undefined
at Client._catchError (/usr/app/node_modules/tdl/dist/client.js:258:24)
at Client._loop (/usr/app/node_modules/tdl/dist/client.js:280:14)
at

Unable to capture message id of sent message in a channel

Below code for send message works but when I try to console log o inside then

  BotClient.invoke({
       '_': "sendMessage",
       chat_id: user_id,
       disable_notification: false,
       from_background: true,
       input_message_content: {
           '_': "inputMessageText",
           text: {text: text},
           disable_web_page_preview: false,
           clear_draft: false
       }
   })
       .then(o => {
           console.log(JSON.stringify(o));
       })
       .catch(e => myError(e));

By running above code... Below JSON is printed

{
  "_": "message",
  "id": 221249545,
  "sender_user_id": 0,
  "chat_id": -1001285598738,
  "sending_state": {
    "_": "messageSendingStatePending"
  },
  "is_outgoing": true,
  "can_be_edited": false,
  "can_be_forwarded": true,
  "can_be_deleted_only_for_self": false,
  "can_be_deleted_for_all_users": true,
  "is_channel_post": true,
  "contains_unread_mention": false,
  "date": 1559043845,
  "edit_date": 0,
  "reply_to_message_id": 0,
  "ttl": 0,
  "ttl_expires_in": 0,
  "via_bot_user_id": 0,
  "author_signature": "",
  "views": 1,
  "media_album_id": "0",
  "content": {
    "_": "messageText",
    "text": {
      "_": "formattedText",
      "text": "Kaka check",
      "entities": []
    }
  }
}

The issue is, I'm not getting the message id... I basically wanted to edit the same message I have sent to a channel... It doesn't happen because if I send the id 221249545 as message _id in editMessageText class https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1edit_message_text.html

It says message not found.

So tried figuring it out... i tried editing the message manually in telegram app. The bot captured below object

{
  "_": "updateMessageContent",
  "chat_id": -1001285598738,
  "message_id": 222298112,
  "new_content": {
    "_": "messageText",
    "text": {
      "_": "formattedText",
      "text": "Kaka check chesava",
      "entities": []
    }
  }
}

The message_id 222298112 is different from id captured inside then I edited the same message again.. It captured below JSON

{
  "_": "updateMessageContent",
  "chat_id": -1001285598738,
  "message_id": 222298112,
  "new_content": {
    "_": "messageText",
    "text": {
      "_": "formattedText",
      "text": "Kaka check chustivz",
      "entities": []
    }
  }
}

So it clear from the fact that id captured inside then is different from actual message_id. Is there anyway we could capture actual message_id of the message we have sent

FLOOD ERROR

How can I detect FLOOD ERROR is occured?
In flood error the client.invoke is resolved and I have no client.on(error) calls

[Question] How to logout/destroy session of user

This is more a question than a problem,

I want to close / destroy the user session but I do not understand how to access the tdlib library method or how to access the user id. I'm using the 'destroy' tdl method but I think it's not right

setProxy exit program?

I'm trying the mult client example. And trying to add a SOCKS5 proxy. Code is like this:

await client1.invoke({
    _: 'setProxy',
    proxy: {
      _: 'proxySocks5',
      server: '192.169.233.35',
      port: 24006
    }
  });
  • I first put this before the client1.connect(). The program just exit directly in this case.
  • If I put it after client1.connect(), after calling setProxy, I could see it's returns {_:'ok'}. However, I doubt it's really getting used because even if I used a wrong proxy, the next call of "getChat" can still return the right result.

An suggestions? Ideally I want proxy to kick in before client even trying to connect

Failed to path auth

I just started to deal with the tdl library and I have a lot of questions. Maybe I don't understand some conceptual things. I'm trying to use a typical example, but I have nothing.

I can not pass authorization. As far as I understand, after I try to log in with client.login, I have to enter the "code", which TG sends in SMS or in the client, which I have already authorized. But in the examples there is no information on how I can enter this code for authorization to perform subsequent functions.

Moreover, having read the closed issues - I understand that certain objects have much more parameters. For example, when creating a client, i can specify databaseDirectory. Where can I read about the binding TDLib functions and this library?

Impossible to set client Invalid ELF header

I have been trying to establish a client in NodeJS for several days but it is being impossible for me since I often get these errors:

Using the repo example, setting the apiId and the apiHash and making a console.log () returns the following:

Client {
  _options:
   { apiId: XXXXXXX,
     apiHash: 'XXXXXXXXXXXXXXXXXXXX',
     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 } },
  _emitter:
   EventEmitter { _events: { 'auth-needed': [EE] }, _eventsCount: 1 },
  _fetching: Map {},
  _tdlib: '/home/isco/userbot/iscobot/libtdjson.so',
  _client: undefined,
  _connectionState: { _: 'connectionStateConnecting' },
  _connectResolver: [Function],
  _connectRejector: [Function],
  _authNeeded: false,
  _loginDetails: undefined,
  _loginResolver: [Function],
  _loginRejector: [Function],
  _paused: false,
  connect: [Function],
  login: [Function],
  connectAndLogin: [AsyncFunction],
  pause: [Function],
  resume: [Function],
  on: [Function],
  once: [Function],
  off: [Function],
  addListener: [Function],
  removeListener: [Function],
  emit: [Function],
  invoke: [AsyncFunction],
  invokeFuture: [Function],
  destroy: [Function],
  setLogFatalErrorCallback: [Function],
  execute: [Function] }

But in turn it returns this and does not create the _td_database or _td_files folders:

(node:17302) UnhandledPromiseRejectionWarning: Error while creating client: TypeError: this._tdlib.execute is not a function
(node:17302) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:17302) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process
with a non-zero exit code.

I have also tried to set the path of the tdlibjson.so file but without any result

I am currently using the Windows subsystem, but I also have it in a raspberry and the same thing happens to me.
If someone could enlighten me or help me, I would be very grateful.

Thanks in advance

Add the ability to ignore updates from the client

I set the tdlibParameters fields in this way.

use_file_database: true,
use_chat_info_database: true,
use_message_database: true,
use_secret_chats: false,
enable_storage_optimizer: false

But after a period of time, messages are cleared and an updateDeleteMessages event is sent with the value of from_cache == true.
I want to ignore the updateDeleteMessages with the value of from_cache == true by the client.

Question about lib usage

Hi @Bannerets just a question if you will.

When I run npm install tdl I get the following

npm ERR! code ENOSELF
npm ERR! Refusing to install package with name "tdl" under a package
npm ERR! also called "tdl". Did you name your project the same
npm ERR! as the dependency you're installing?

I have already build TDLib. Do I need to link the binary of TDLib somewhere before I execute npm install tdl ?

Thank you

Installation on ARM64 is failing

> node-gyp rebuild

make: Entering directory '/var/apps/Convrt/node_modules/ref-napi/build'
  CC(target) Release/obj.target/nothing/node_modules/node-addon-api/src/nothing.o
  AR(target) Release/obj.target/node_modules/node-addon-api/src/nothing.a
  COPY Release/nothing.a
  CXX(target) Release/obj.target/binding/src/binding.o
  SOLINK_MODULE(target) Release/obj.target/binding.node
  COPY Release/binding.node
make: Leaving directory '/var/apps/Convrt/node_modules/ref-napi/build'

> [email protected] install /var/apps/Convrt/node_modules/ffi-napi
> node-gyp rebuild

make: Entering directory '/var/apps/Convrt/node_modules/ffi-napi/build'
  CC(target) Release/obj.target/nothing/../node-addon-api/src/nothing.o
  AR(target) Release/obj.target/../node-addon-api/src/nothing.a
  COPY Release/nothing.a
  CC(target) Release/obj.target/ffi/deps/libffi/src/prep_cif.o
In file included from ../deps/libffi/src/prep_cif.c:27:0:
../deps/libffi/include/ffi_common.h:17:23: fatal error: fficonfig.h: No such file or directory
compilation terminated.
deps/libffi/ffi.target.mk:117: recipe for target 'Release/obj.target/ffi/deps/libffi/src/prep_cif.o' failed
make: *** [Release/obj.target/ffi/deps/libffi/src/prep_cif.o] Error 1
make: Leaving directory '/var/apps/Convrt/node_modules/ffi-napi/build'
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR! stack     at ChildProcess.emit (events.js:198:13)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:248:12)
gyp ERR! System Linux 4.19.53-mainline-rev1
gyp ERR! command "/usr/bin/node" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /var/apps/Convrt/node_modules/ffi-napi
gyp ERR! node -v v10.16.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
npm WARN [email protected] No description
npm WARN [email protected] No repository field.

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2019-07-02T09_14_16_579Z-debug.log

Question about Module(). in the createClient function

Hi,
I just started trying out your package.
The documentation tells me to use this
function createClient (options) { return new Promise(resolve => { Module().then(module => { const tdlib = new TDLib(module) resolve(new Client(tdlib, options)) }) }) }
to create a client. However Module().then(... is unresolved.
Do I need the npm package "module" (https://www.npmjs.com/package/module) for it to work?
If so I guess a update of the readme would be useful?

Change Typescript typing file to a definition file

Please change the Typescript typing file to a definition file. TypeScript will treat it differently, and TSLint will ignore it, as opposed to my current situation where TSLint is registering thousands of errors due to the use of single quotes instead of double quotes.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.