From cadf589a6d602a1c1676a8aad9640b9ce3ffa427 Mon Sep 17 00:00:00 2001 From: alina sireneva Date: Fri, 17 Jan 2025 09:19:40 +0300 Subject: [PATCH] docs: updated docs to latest ver --- docs/guide/advanced/session-convert.md | 26 +++++++++++++++ docs/guide/index.md | 26 ++++----------- docs/guide/intro/errors.md | 12 ++----- docs/guide/intro/updates.md | 11 +++---- docs/guide/topics/files.md | 6 ++-- docs/guide/topics/inline-mode.md | 2 +- docs/guide/topics/storage.md | 32 +++++++++++-------- docs/guide/topics/transport.md | 44 +++++++++++--------------- 8 files changed, 80 insertions(+), 79 deletions(-) diff --git a/docs/guide/advanced/session-convert.md b/docs/guide/advanced/session-convert.md index 5616a03e..2532f27e 100644 --- a/docs/guide/advanced/session-convert.md +++ b/docs/guide/advanced/session-convert.md @@ -43,6 +43,19 @@ const client = new TelegramClient({ ... }) await client.importSession(convertFromGramjsSession("...")) ``` +### Store session + +In some version GramJS added support for storing session as a directory of files, +and can be imported like so: + +```ts +import { readGramjsStoreSession, convertFromGramjsSession } from '@mtcute/convert' + +const client = new TelegramClient({ ... }) +const session = await readGramjsStoreSession('/path/to/session') +await client.importSession(convertFromGramjsSession(session)) +``` + ## [MTKruto](https://github.com/MTKruto/MTKruto) ```ts @@ -52,6 +65,19 @@ const client = new TelegramClient({ ... }) await client.importSession(convertFromMtkrutoSession("...")) ``` +## [Telegram Desktop](https://github.com/telegramdesktop/tdesktop) (tdata) + +```ts +import { convertFromTdata } from '@mtcute/convert' + +const client = new TelegramClient({ ... }) +await client.importSession(convertFromTdata({ + path: '/path/to/tdata', + ignoreVersion: true // note: this might break + // passcode: '123456' // if you have a passcode +})) +``` + ## Backwards If you need to convert a session from mtcute to another library, you can use the `convertTo*` functions instead: diff --git a/docs/guide/index.md b/docs/guide/index.md index 4435299a..4329969d 100755 --- a/docs/guide/index.md +++ b/docs/guide/index.md @@ -60,7 +60,7 @@ no extra steps are required. ## Bun -Experimental support for Bun is provided in `@mtcute/bun` package, and +Support for Bun is provided in `@mtcute/bun` package, and Bun is also supported in `@mtcute/create-bot`. ```bash @@ -71,7 +71,7 @@ bun add @mtcute/bun ## Deno -Experimental support for Deno is provided in `@mtcute/deno` package, which is published +Support for Deno is provided in `@mtcute/deno` package, which is published to the [jsr.io](https://jsr.io) registry: ```ts @@ -137,34 +137,20 @@ See also: [Tree-shaking](/guide/advanced/treeshaking.md) ## Other runtimes -mtcute strives to be as runtime-agnostic as possible, so it should work in any environment that supports -some basic ES2020 features. +mtcute strives to be as runtime-agnostic as possible, so it should work in any environment that supports some basic ES2020 features (notably, bigints. There's an [unofficial fork](https://github.com/cyan-2048/mtcute) that uses polyfills for bigints, if you're into that). In case your runtime of choice is not listed above, you can try using `@mtcute/core` directly -You will need to provide your own implementations of storage, networking and crypto - feel free to take a -look at web/node implementations for reference (or even extend them to better fit your needs, e.g. if some runtime -only partially supports some Node.js APIs). +You will need to provide your own implementations of storage, networking and crypto - feel free to take a look at web/node implementations for reference (or even extend them to better fit your needs, e.g. if some runtime only partially supports some Node.js APIs). ```ts import { TelegramClient } from '@mtcute/core/client.js' -import { setPlatform } from '@mtcute/core/platform.js' - -setPlatform(new MyPlatform()) const tg = new TelegramClient({ ..., storage: new MyStorage(), crypto: new MyCrypto() - transport: () => new MyTransport(), + transport: new MyTransport(), + platform: new MyPlatform(), }) ``` - -::: info -You only need to call `setPlatform` once, before creating any clients. -Platform is set once globally and cannot be changed afterwards. -It is safe to call `setPlatform` multiple times, as long as the constructor is the same - it will be ignored if the platform is already set. - -A good starting point might be to use [WebPlatform](https://ref.mtcute.dev/classes/_mtcute_web.WebPlatform.html), -since it implements everything in portable JavaScript. -::: \ No newline at end of file diff --git a/docs/guide/intro/errors.md b/docs/guide/intro/errors.md index 9806b421..0c20bee7 100755 --- a/docs/guide/intro/errors.md +++ b/docs/guide/intro/errors.md @@ -103,14 +103,7 @@ You can handle these errors using `TelegramClient#onError`: ```ts const tg = new TelegramClient(...) -tg.onError((err, conn) => { - if (conn) { - // `err` is the error - // `conn` is the connection where the error happened - console.log(err, conn) - } - - // `err` is not a connection-related error +tg.onError.add((err) => { console.log(err) }) ``` @@ -119,7 +112,8 @@ tg.onError((err, conn) => { mtcute handles reconnection and stuff automatically, so you don't need to call `.connect()` again! -This should primarily be used for logging and debugging +This should primarily be used for logging and debugging, as well as some +edge cases where you might need access to low-level connection state ::: ## Dispatcher errors diff --git a/docs/guide/intro/updates.md b/docs/guide/intro/updates.md index 1ab14383..84ac986e 100755 --- a/docs/guide/intro/updates.md +++ b/docs/guide/intro/updates.md @@ -38,29 +38,28 @@ const tg = new TelegramClient({ The updates themselves are dispatched on the client as events (see [reference](https://ref.mtcute.dev/classes/_mtcute_core.index.TelegramClient.html#on)): ```ts -tg.on('new_message', (msg) => { +tg.onNewMessage.add((msg) => { console.log(msg.text) }) // You can also handle any supported update at once: -tg.on('update', (upd) => { +tg.onUpdate.add((upd) => { if (upd.name === 'new_message') { console.log(upd.data.text) } }) // As well as raw MTProto updates: -tg.on('raw_update', (upd, users, chats) => { +tg.onRawUpdate.add((upd, users, chats) => { console.log(upd._) }) ``` ::: tip -Client events are based on EventEmitter. It expects handlers to be synchronous, -so if you want to do something async, make sure to also handle the errors: +The handlers should be synchronous, so if you want to do something async, make sure to also handle the errors: ```ts -tg.on('new_message', async (msg) => { +tg.onNewMessage.add(async (msg) => { try { await msg.answerText('test') } catch (e) { diff --git a/docs/guide/topics/files.md b/docs/guide/topics/files.md index efd84bff..9613ce76 100755 --- a/docs/guide/topics/files.md +++ b/docs/guide/topics/files.md @@ -9,7 +9,7 @@ To download a file, just use `downloadIterable`, `downloadStream`, `downloadBuffer`or `downloadToFile` method on the object that represents a file, for example: ```ts -tg.on('new_message', async (msg) => { +tg.onNewMessage.add(async (msg) => { if (msg.media?.type === 'photo') { await tg.downloadToFile('download.jpg', msg.media) } @@ -161,7 +161,7 @@ them you'll need to have some understanding of how files in MTProto work. File ID is available in `.fileId` field: ```ts -tg.on('new_message', async (msg) => { +tg.onNewMessage.add(async (msg) => { if (msg.media?.type === 'photo') { console.log(msg.media.fileId) } @@ -181,7 +181,7 @@ for different users/bots. Unique File ID is available in `.uniqueFileId` field: ```ts -tg.on('new_message', async (msg) => { +tg.onNewMessage.add(async (msg) => { if (msg.media?.type === 'photo') { console.log(msg.media.uniqueFileId) } diff --git a/docs/guide/topics/inline-mode.md b/docs/guide/topics/inline-mode.md index 7b669ad9..4259b0ef 100755 --- a/docs/guide/topics/inline-mode.md +++ b/docs/guide/topics/inline-mode.md @@ -15,7 +15,7 @@ Instead of Dispatcher, you can also use client events (however you will miss features that Dispatcher provides): ```ts -tg.on('inline_query', async (query) => { +tg.onInlineQuery.add(async (query) => { await query.answer([]) }) ``` diff --git a/docs/guide/topics/storage.md b/docs/guide/topics/storage.md index 2c7dbf25..63037cc1 100755 --- a/docs/guide/topics/storage.md +++ b/docs/guide/topics/storage.md @@ -29,15 +29,18 @@ and also caching won't work past a single run. ## SQLite storage -The preferred storage for a Node.js application is the one using SQLite, +The preferred storage for a server application is the one using SQLite, because it does not require loading the entire thing into memory, and is also faster than simply reading/writing a file. -mtcute implements it in a separate package, `@mtcute/sqlite`, and internally -uses [better-sqlite3](https://www.npmjs.com/package/better-sqlite3) +mtcute implements sqlite storages in runtime-specific packages, +using the best libraries available for each runtime: + - Node.js: [better-sqlite3](https://www.npmjs.com/package/better-sqlite3) + - Bun: `bun:sqlite` + - Deno: [@db/sqlite](https://jsr.io/@db/sqlite) ```ts{4} -import { SqliteStorage } from '@mtcute/sqlite' +import { SqliteStorage } from '@mtcute/node' // or '@mtcute/bun' / '@mtcute/deno' const tg = new TelegramClient({ storage: new SqliteStorage('my-account.session') @@ -45,7 +48,7 @@ const tg = new TelegramClient({ ``` ::: tip -If you are using `@mtcute/node`, SQLite storage is the default, +In runtime-specific packages, SQLite storage is the default, and you can simply pass a string with file name instead of instantiating `SqliteStorage` manually: @@ -56,8 +59,7 @@ const tg = new TelegramClient({ ``` ::: -To improve performance, `@mtcute/sqlite` by default uses -WAL mode ([Learn more](https://github.com/JoshuaWise/better-sqlite3/blob/master/docs/performance.md)). +To improve performance, we use WAL mode by default ([Learn more](https://github.com/JoshuaWise/better-sqlite3/blob/master/docs/performance.md)). When using WAL, along with your SQLite file there may also be `-shm` and `-wal` files. If you don't like seeing those files, @@ -81,8 +83,11 @@ const tg = new TelegramClient({ }) ``` +> Note that the string passed will be used as-is as the database name, +> so you might want to prefix it to avoid conflicts. + ::: tip -In the browser, IndexedDB storage is the default, +In `@mtcute/web`, IndexedDB storage is the default, and you can simply pass a string with file name instead of instantiating `IdbStorage` manually: @@ -144,14 +149,14 @@ Most of the string is occupied by 256 bytes long MTProto authorization key, which, when Base64 encoded, results in **344** characters. Additionally, information about user (their ID and whether the user is a bot) and their DC -is included, which results in an average of **407** characters +is included, which results in an average of ~**400** characters ::: ## Implementing custom storage -The easiest way to implement a custom storage would be to make a subclass of `MemoryStorage`, -or check the [source code of SqliteStorage](https://github.com/mtcute/mtcute/blob/master/packages/sqlite/src/index.ts) -and implement something similar with your DB of choice. +The easiest way to implement a custom storage would be to make a subclass of `MemoryStorage`. + +Additionaly, mtcute abstracts away the sqlite storage implementation, so you can use the the `BaseSqliteStorage` API to implement sqlite storage using your library of choice (see [Node.js implementation](https://github.com/mtcute/mtcute/tree/master/packages/node/src/sqlite) for reference). ### Architecture @@ -163,8 +168,7 @@ A storage provider in mtcute is composed of: more efficient and organized access to the data. Repositories are registered in the driver and are used to access the data in the storage -Such composable architecture allows for custom storages to implement a specific set of repositories, -and to reuse the same driver for different providers. +Such composable architecture allows for custom storages to implement a specific set of repositories, and to reuse the same driver for different providers. In mtcute, these sets of repositories are defined: - [IMtStorageProvider](https://ref.mtcute.dev/types/_mtcute_core.index.IMtStorageProvider.html), used by `BaseTelegramClient` for low-level diff --git a/docs/guide/topics/transport.md b/docs/guide/topics/transport.md index 546ba7b9..0a8d55e4 100755 --- a/docs/guide/topics/transport.md +++ b/docs/guide/topics/transport.md @@ -15,7 +15,7 @@ import { TcpTransport } from '@mtcute/node' const tg = new TelegramClient({ // ... - transport: () => new TcpTransport() + transport: new TcpTransport() }) ``` @@ -35,7 +35,7 @@ import { WebSocketTransport } from '@mtcute/web' const tg = new TelegramClient({ // ... - transport: () => new WebSocketTransport() + transport: new WebSocketTransport() }) ``` @@ -46,19 +46,14 @@ In browser, it is used automatically, you don't need to pass this explicitly ## HTTP(s) Proxy transport To access Telegram via HTTP(s) proxy, you can use -`HttpProxyTcpTransport`, which is provided -by `@mtcute/http-proxy` (Node.js only): - -```bash -pnpm add @mtcute/http-proxy -``` +`HttpProxyTcpTransport`, which is provided by runtime-specific packages: ```ts{5-8} -import { HttpProxyTcpTransport } from '@mtcute/http-proxy' +import { HttpProxyTcpTransport } from '@mtcute/node' // or '@mtcute/bun' / '@mtcute/deno' const tg = new TelegramClient({ // ... - transport: () => new HttpProxyTcpTransport({ + transport: new HttpProxyTcpTransport({ host: '127.0.0.1', port: 8080 }) @@ -68,19 +63,14 @@ const tg = new TelegramClient({ ## SOCKS4/5 Proxy transport To access Telegram via SOCKS4/5 proxy, you can use -`SocksTcpTransport`, which is provided -by `@mtcute/socks-proxy` (Node.js only): - -```bash -pnpm add @mtcute/socks-proxy -``` +`SocksProxyTcpTransport`, which is provided by runtime-specific packages: ```ts{5-8} -import { SocksTcpTransport } from '@mtcute/socks-proxy' +import { SocksProxyTcpTransport } from '@mtcute/node' // or '@mtcute/bun' / '@mtcute/deno' const tg = new TelegramClient({ // ... - transport: () => new SocksTcpTransport({ + transport: new SocksProxyTcpTransport({ host: '127.0.0.1', port: 8080 }) @@ -90,18 +80,14 @@ const tg = new TelegramClient({ ## MTProxy transport To access Telegram via MTProxy (MTProto proxy), you can use -`MtProxyTcpTransport`, which is provided by `@mtcute/mtproxy` (Node.js only): - -```bash -pnpm add @mtcute/mtproxy -``` +`MtProxyTcpTransport`, which is provided by runtime-specific packages: ```ts{5-8} -import { MtProxyTcpTransport } from '@mtcute/mtproxy' +import { MtProxyTcpTransport } from '@mtcute/node' // or '@mtcute/bun' / '@mtcute/deno' const tg = new TelegramClient({ // ... - transport: () => new MtProxyTcpTransport({ + transport: new MtProxyTcpTransport({ host: '127.0.0.1', port: 8080, secret: '0123456789abcdef0123456789abcdef' @@ -122,9 +108,11 @@ could be used to change proxy used to connect to Telegram. To change the transport, simply call `changeTransport`: ```ts -tg.changeTransport(() => new MtProxyTcpTransport({...})) +tg.mt.network.changeTransport(new MtProxyTcpTransport({...})) ``` +> Note: the `mt` field is only available on `BaseTelegramClient` instances. + ## Implementing custom transport When targeting an environment which is not supported already, @@ -135,3 +123,7 @@ You can check out source code for the bundled transports to get the basic idea [here](https://github.com/mtcute/mtcute/tree/master/packages/core/src/network/transports), and re-use any packet codecs that are included. + +Transports in mtcute are built on top of [`@fuman/net`](https://github.com/teidesu/fuman/tree/main/packages/net), which is an in-house networking abstraction library used by mtcute. +It is a very powerful library which makes it super easy to implement custom transports. +There isn't much documentation, but feel free to check out the source code [here](https://github.com/teidesu/fuman/blob/main/packages/node/src/net/connection.ts). \ No newline at end of file