Tdl
Node.js bindings to TDLib 🥒
Install / Use
/learn @eilvelia/TdlREADME
tdl

tdl is a fairly simple JavaScript wrapper for TDLib (Telegram Database library), a library for creating Telegram clients or bots.
- Requirements
- Installation
- Getting started
- API
- Generating types
- Other JavaScript runtimes
- Troubleshooting
- Issue tracker
<a name="requirements"></a>
Requirements
- Node.js v16 or newer
- The tdjson shared library (
libtdjson.soon Linux,libtdjson.dylibon macOS,tdjson.dllon Windows), of TDLib version 1.8.0 or newer - In rare cases, a C++ compiler and Python installed to build the node addon[^1]
[^1]: tdl is packaged with pre-built addons for Windows (x86_64), Linux (x86_64, arm64; glibc >= 2.22 or musl), and macOS (x86_64, arm64; v11.0+). 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. arm64 binaries are not tested in CI. Linux binaries are statically linked against libstdc++.
<a name="installation"></a>
Installation
- Install tdl:
npm install tdl - Additionally install pre-built TDLib libraries (
npm install prebuilt-tdlib) or build TDLib yourself
To use tdl, you also need to get TDLib itself, which is dynamically loaded by
tdl. A convenient option is to use the prebuilt-tdlib package (which is
currently separate from tdl). Alternatively, you can build TDLib by following
its build instructions, for example in cases where prebuilt-tdlib is not
available for your platform, does not support the desired TDLib version, you
need a patched TDLib, or for other reasons.
[!TIP] When building TDLib, the libraries can be installed into the system using
cmake --install .(optionally specify the--prefixoption, the default is/usr/local) after TDLib has been built successfully. This command may requiresudo.
prebuilt-tdlib
prebuilt-tdlib supports x86_64 & arm64 Linux, x86_64 & arm64
macOS, and x86_64 Windows. An example of using libraries from prebuilt-tdlib
is present in the section below. See the README of prebuilt-tdlib for
additional information.
<a name="getting-started"></a>
Getting started
// Import using CommonJS:
const tdl = require('tdl')
// Configure tdl to use the tdjson shared library from the prebuilt-tdlib
// package (should be installed separately)
const { getTdjson } = require('prebuilt-tdlib')
tdl.configure({ tdjson: getTdjson() })
// Instead of using the aforementioned prebuilt-tdlib, you can configure
// tdl to load libtdjson from specified filename, for example:
// tdl.configure({ tdjson: '/usr/local/lib/libtdjson.dylib' })
// With no configuration, tdl loads libtdjson from the system search paths.
// 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 })
// Create a client. It is mandatory to pass apiId and apiHash, these can be
// obtained at https://my.telegram.org/
const client = tdl.createClient({
apiId: 2222, // Replace with your api_id
apiHash: '0123456789abcdef0123456789abcdef' // Replace with your api_hash
})
client.on('error', console.error)
// Aside of sending responses to your requests, TDLib pushes to you
// events called "updates", which can be received as follows:
client.on('update', update => {
console.log('Received 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()
// Call 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 finishes gracefully and the JS runtime can
// exit the process.
await client.close()
}
main().catch(console.error)
Instead of using require, one can import tdl in an
EcmaScript module through the interoperability with CommonJS:
import * as tdl from 'tdl' (or import only some functions:
import { createClient } from 'tdl').
The API reference of the TDLib methods, which are called using client.invoke,
can be found at:
- https://core.telegram.org/tdlib/docs/annotated.html,
- the td_api.tl file in the TDLib repository (written as a schema in the TL language),
- if the TypeScript types for TDLib are installed, the documentation can be
browsed directly in the editor, using the editor's autocompletion menu or the
tdlib-types.d.tsfile (the types are annotated with JSDoc comments).
In the TDLib schema, 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 mapped to the number JavaScript type.
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.
If you use TypeScript, types for TDLib can be imported using
import type * as Td from 'tdlib-types', see also Generating types.
<a name="api"></a>
API
[!NOTE] More exhaustive documentation can be found in the TypeScript declaration file.
tdl.configure(options: TDLibConfiguration) => void
Configure several parameters such as libtdjson filename or verbosity level. This
function should be called before tdl.createClient or tdl.execute. Can be
called multiple times; only present fields are set.
The possible parameters are:
tdl.configure({
// Path to the shared 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. Defaults to the empty string.
libdir: '/usr/local/lib',
// Set the verbosity level of TDLib. Defaults to 1.
verbosityLevel: 1,
// Advanced options:
useOldTdjsonInterface: false,
receiveTimeout: 10,
})
Some examples:
tdl.configure({ tdjson: '/root/libtdjson.so', verbosityLevel: 5 })tdl.configure({ libdir: '/usr/local/lib', tdjson: 'libtdjson.dylib.1.8.6' })tdl.configure({ libdir: __dirname })(use libtdjson from the directory of the current script, in CJS)tdl.configure({ tdjson: require('prebuilt-tdlib').getTdjson() })(use libtdjson from prebuilt-tdlib)
The path concatenation of libdir + tdjson is directly passed to
[dlopen][dlopen] (Unix) or [LoadLibrary][LoadLibraryW] (Windows).
This function must be called before TDLib is initialized, that is, before
any of createClient / execute are called.
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 ...
})
createClient accepts options of the following interface (expressed in TypeScript):
type ClientOptions = {
apiId: number, // Can be obtained at https://my.telegram.org
apiHash: string, // Can be obtained at https://my.telegram.org
databaseDirectory?: string, // Path, relative to cwd (defaults to '_td_database')
filesDirectory?: string, // Path, relative to cwd (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
skipOldUpdates?: boolean // Advanced option
}
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 the 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 likely want to change device_model and other
parameters.
