tdl

repository·main·Indexed 19 days ago

https://github.com/eilvelia/tdl

A lightweight JavaScript wrapper for TDLib (Telegram Database library) that enables developers to build Telegram clients or bots using Node.js. The ecosystem includes prebuilt shared libraries via prebuilt-tdlib and a CLI utility, tdl-install-types, for generating TypeScript and Flow type definitions from TDLib sources, shared libraries, or TL schemas.

Tokens
11.7K
Snippets
47
Records
61
Agent score
66%

What's inside tdl

  1. Use tdl in Node.js Worker Threads

    main

    New tdjson interface

    By default, tdl with the new tdjson interface can be used in only one thread.

    Old tdjson interface

    If you need to use tdl in multiple worker threads, configure it using: tdl.configure({ useOldTdjsonInterface: true }).

    Caveats for the old interface:

    • The tdjson and libdir options in tdl.configure will be ignored on subsequent initializations.
    • It is recommended to set tdl.configure({ verbosityLevel: 'default' }) so the verbosity level is set only once.
    • Do not share the client instance across different threads.
    // To enable multi-thread support via the old interface
    tdl.configure({ useOldTdjsonInterface: true });
  2. Handle updates with `client.on()` or `client.iterUpdates()`

    main

    There are two ways to receive updates from TDLib:

    1. Event Listeners (client.on)

    Attach a callback to the 'update' event. It is highly recommended to also attach a listener to the 'error' event to prevent unhandled promise rejections.

    client.on('update', (update) => {
      console.log('New update:', update)
    })
    
    client.on('error', console.error)

    2. Async Iterators (client.iterUpdates)

    Introduced in tdl v8.0.0, this allows you to process updates using an async loop. This is often cleaner for sequential processing.

    for await (const update of client.iterUpdates()) {
      console.log('Received update:', update)
      if (update._ === 'updateOption' && update.name === 'my_id') {
        break
      }
    }

    Note: The 'close' event is emitted after authorizationStateClosed. Once the client is closed, it can no longer be used to send requests.

    // Using event listeners
    client.on('update', (update) => {
      console.log('New update:', update)
    })
    
    // Using async iterators (v8.0.0+)
    for await (const update of client.iterUpdates()) {
      console.log('Received update:', update)
    }
  3. Understand the role of @prebuilt-tdlib/types-dev

    main
    The @prebuilt-tdlib/types-dev package provides TypeScript type definitions for TDLib. These types are generated using tdl-install-types and are part of the broader prebuilt-tdlib ecosystem. Use this package when you need type safety for TDLib interactions within a TypeScript project using prebuilt binaries.
  4. Configure tdl to load the TDLib shared library

    main

    By default, tdl attempts to load libtdjson from system search paths. You can explicitly configure how it finds the library using tdl.configure().

    Common configuration patterns:

    • Using prebuilt-tdlib: Use getTdjson() from the prebuilt-tdlib package.
    • Specifying a filename: Provide the absolute path to the .so, .dylib, or .dll file.
    • Specifying a directory: Use libdir to tell tdl where to search for the library (e.g., the current directory).
    const tdl = require('tdl')
    const { getTdjson } = require('prebuilt-tdlib')
    
    // Option 1: Use prebuilt-tdlib (Recommended)
    tdl.configure({ tdjson: getTdjson() })
    
    // Option 2: Use a specific file path
    // tdl.configure({ tdjson: '/usr/local/lib/libtdjson.dylib' })
    
    // Option 3: Set a search directory
    // tdl.configure({ libdir: __dirname })
  5. Use tdl in Bun or Deno

    main

    Bun

    Since Bun is Node.js-compatible and supports Node-API, tdl generally works out of the box, though stability may vary.

    Deno

    You can import tdl via Node compatibility using import * as tdl from 'npm:tdl'.

    Requirement: You must use Deno version 1.44.2 or greater, as older versions had broken Node-API implementations.

    Browser Support

    tdl depends on native libraries and cannot be used in the browser. If you need TDLib in a browser environment, you must use a WebAssembly (WASM) compilation of TDLib (e.g., via the tdweb library).

  6. Install tdl and TDLib

    main

    To use tdl, you must install the wrapper and provide the tdjson shared library. The easiest way is to use the prebuilt-tdlib package.

    1. Install tdl: npm install tdl
    2. Install pre-built TDLib libraries: npm install prebuilt-tdlib (recommended)

    Alternatively, you can build TDLib yourself following the official TDLib build instructions. If you build it manually, you can install the libraries to your system using cmake --install ..

    npm install tdl
    npm install prebuilt-tdlib
  7. Generate TypeScript types with `tdl-install-types`

    main

    To get autocompletion and type safety for the 2500+ TDLib methods, you should use TypeScript. While prebuilt-tdlib (v1.8.52+) includes types, you can generate custom types for any TDLib version using npx tdl-install-types.

    Usage Examples

    • For installed prebuilt-tdlib: npx tdl-install-types prebuilt-tdlib
    • For a specific shared library file: npx tdl-install-types ./libtdjson.so
    • For a TDLib git commit: npx tdl-install-types 0ada45c3618108a62806ce7d9ab435a18dac1aab
    • For a TDLib git tag: npx tdl-install-types v1.8.0
    • For a TDLib branch: npx tdl-install-types master
    • From a .tl file: npx tdl-install-types ./td_api.tl

    Integration

    Types are generated into tdlib-types.d.ts. You can import them using the tdlib-types module name without needing to install a separate npm package:

    import type * as Td from 'tdlib-types'
    
    // Usage:
    const msg: Td.Message = ...
    $ npx tdl-install-types prebuilt-tdlib
  8. Create and use a Telegram client with tdl

    main

    To interact with Telegram, create a client using tdl.createClient(). You must provide an apiId and apiHash obtained from my.telegram.org.

    Key Lifecycle Methods:

    • client.login(): Authenticates the session. By default, this prompts for credentials in the console. Use client.loginAsBot('<TOKEN>') to log in as a bot.
    • client.invoke({ ... }): Calls a TDLib method. Note that tdl renames the TDLib @type field to _ for convenience.
    • client.on('update', callback): Listens for asynchronous updates pushed by TDLib.
    • client.close(): Gracefully closes the connection and allows the process to exit.
    const tdl = require('tdl')
    const { getTdjson } = require('prebuilt-tdlib')
    
    tdl.configure({ tdjson: getTdjson() })
    
    const client = tdl.createClient({
      apiId: 2222, // Replace with your api_id
      apiHash: '0123456789abcdef0123456789abcdef' // Replace with your api_hash
    })
    
    client.on('error', console.error)
    client.on('update', update => {
      console.log('Received update:', update)
    })
    
    async function main () {
      await client.login()
    
      // Example: getMe
      const me = await client.invoke({ _: 'getMe' })
      console.log('My user:', me)
    
      // Example: getChats
      const chats = await client.invoke({
        _: 'getChats',
        chat_list: { _: 'chatListMain' },
        limit: 10
      })
      console.log('A part of my chat list:', chats)
    
      await client.close()
    }
    
    main().catch(console.error)
  9. Install prebuilt-tdlib

    main

    To install the latest supported version of the TDLib shared libraries, run:

    npm install prebuilt-tdlib

    To install a specific TDLib version, use the td- dist-tags. For example, to install TDLib v1.8.50:

    npm install prebuilt-tdlib@td-1.8.50

    You can list all available versions by running:

    npm info prebuilt-tdlib dist-tags

    Or use jq for a sorted list of available TDLib versions:

    npm info prebuilt-tdlib dist-tags --json | jq 'to_entries | sort_by(.value) | .[].key | select(startswith("td-"))'
    npm install prebuilt-tdlib
  10. Use tdl-install-types to generate TDLib types

    main

    The tdl-install-types CLI utility generates TypeScript (and optionally Flow) types for TDLib. These types are designed to be used with the tdl library. By default, the utility creates a tdlib-types.d.ts file, which you should commit to your version control system (e.g., git).

    You can run the utility using npx without needing to install it globally.

    $ npx tdl-install-types [<options>] [<target>]
  11. How tdl-install-types determines the target type

    main

    If you do not explicitly provide a type flag (--lib, --tl, or --git-ref), tdl-install-types uses heuristics based on the <target> argument:

    1. Shared Library: If <target> ends with .so, .dylib, or .dll, it is treated as a library file (--lib).
    2. TL Schema: If <target> ends with .tl, it is treated as a TL schema file (--tl).
    3. Prebuilt TDLib: If <target> is exactly prebuilt-tdlib, it uses the installed prebuilt-tdlib package.
    4. Git Reference: Otherwise, the target is treated as a git reference (commit hash, tag, or branch) in the TDLib repository (--git-ref).
    5. Default: If no target is provided, it defaults to prebuilt-tdlib.