|
1 | | -# Telegram Flow |
| 1 | +# Telegram Flow for TDLib |
2 | 2 |
|
3 | | -Kotlin Coroutines extensions for Telegram API [TDLib](https://github.com/tdlib/td) (Telegram Database |
4 | | - library) |
| 3 | +[](https://jitpack.io/v/#akrafts-gpt/td-ktx) |
5 | 4 |
|
6 | | -## Using library |
| 5 | +Telegram Flow is a Kotlin-first extension toolkit for [TDLib](https://github.com/tdlib/td) that turns callback-based Telegram API calls into coroutines and flows. It keeps your client code concise while exposing idiomatic Compose- and coroutine-friendly APIs. |
7 | 6 |
|
8 | | -The main class of the library is [TelegramFlow]. It converts Telegram Updates handlers to the |
9 | | -Kotlin Coroutine Flows and Telegram callback-style Functions to Kotlin Coroutine suspend functions |
| 7 | +## Features |
| 8 | +- **Coroutine wrappers** for every TDLib function so you can `suspend` instead of juggling callbacks. |
| 9 | +- **Flow-based updates** that emit strongly typed Telegram updates with sensible defaults. |
| 10 | +- **Extension interfaces** to organize API access around Telegram entities (users, chats, messages, etc.). |
| 11 | +- **Compose-ready**: works seamlessly with `ViewModel` scopes and state flows. |
10 | 12 |
|
11 | | -### Start using |
| 13 | +## Setup |
| 14 | +Add the library dependency from Maven Central: |
12 | 15 |
|
13 | | -1. Create instance of [TelegramFlow] |
14 | | -2. You can collect flow of TdApi.Objects from the TelegramFlow instance and its [flow extensions]. |
15 | | -3. Call [attachClient] function of the [TelegramFlow] instance to connect it to the Telegram Client. |
16 | | -4. Now you can use numerous [extension functions] to send data to the Telegram API and collect data |
17 | | - from [flow extensions] |
18 | | - |
19 | | -### Using Flows |
| 16 | +```kotlin |
| 17 | +implementation(project(":libtd-ktx")) |
| 18 | +``` |
20 | 19 |
|
21 | | -[Any update](https://core.telegram.org/tdlib/getting-started#handling-updates) listed in TdApi can be collected by corresponding flow extension of the [TelegramFlow]. |
| 20 | +The `libtd-ktx` module exposes TDLib (`com.github.tdlibx:td:1.8.56`) as an API dependency, so no extra TDLib declaration is required. |
22 | 21 |
|
23 | | -```Kotlin |
24 | | -telegramFlow.userStatusFlow().collect { status: TdApi.UpdateUserStatus -> |
25 | | - // collect UpdateUserStatus from Telegram |
26 | | -} |
27 | | -``` |
| 22 | +The project ships a TDLib wrapper module (`libtd-ktx`) and a Compose sample under `sample/` that demonstrates usage with Hilt and the Navigation 3 typed destination APIs. |
28 | 23 |
|
29 | | -For the Updates where there is the only field available inside, Update class is suppress by the flow extension and return data itself, for example: |
| 24 | +## Getting started |
| 25 | +1. Create a single `TelegramFlow` instance and keep it in a long-lived scope (e.g., via DI). |
| 26 | +2. Attach a TDLib client once at startup: |
30 | 27 |
|
31 | | -```Kotlin |
32 | | -telegramFlow.authorizationStateFlow().collect { state: TdApi.AuthorizationState -> |
33 | | - // collect AuthorizationState instead of TdApi.UpdateAuthorizationState since there is no other data inside |
| 28 | +```kotlin |
| 29 | +val telegramFlow = TelegramFlow() |
| 30 | +telegramFlow.attachClient() |
| 31 | +``` |
| 32 | + |
| 33 | +3. Provide required TDLib parameters when prompted by the authorization state flow: |
| 34 | + |
| 35 | +```kotlin |
| 36 | +telegramFlow.authorizationStateFlow().collect { state -> |
| 37 | + if (state is TdApi.AuthorizationStateWaitTdlibParameters) { |
| 38 | + telegramFlow.setTdlibParameters( |
| 39 | + databaseDirectory = "/data/user/0/<your.package>/files/td", |
| 40 | + apiId = BuildConfig.TELEGRAM_APP_ID, |
| 41 | + apiHash = BuildConfig.TELEGRAM_APP_HASH, |
| 42 | + // ...other parameters |
| 43 | + ) |
| 44 | + } |
34 | 45 | } |
35 | 46 | ``` |
36 | 47 |
|
37 | | -### Using Functions |
| 48 | +4. Send authentication information with coroutine calls: |
38 | 49 |
|
39 | | -[Any funcrion](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_function.html) listed in TdApi can be called via corresponding coroutine extension |
| 50 | +```kotlin |
| 51 | +telegramFlow.setAuthenticationPhoneNumber(phone, null) |
| 52 | +telegramFlow.checkAuthenticationCode(code) |
| 53 | +telegramFlow.checkAuthenticationPassword(password) |
| 54 | +``` |
| 55 | + |
| 56 | +## Collecting updates |
| 57 | +Every TDLib update has a matching flow extension. Example: tracking user presence changes. |
40 | 58 |
|
41 | | -```Kotlin |
42 | | -suspend fun sendCode(code: String) { |
43 | | - api.checkAuthenticationCode(code) // send TdApi.CheckAuthenticationCode(code) to the Client |
| 59 | +```kotlin |
| 60 | +telegramFlow.userStatusFlow().collect { status -> |
| 61 | + val user = telegramFlow.getUser(status.userId) |
| 62 | + // update UI with latest user status |
44 | 63 | } |
45 | 64 | ``` |
46 | 65 |
|
47 | | -### Using extensions interfaces |
| 66 | +For updates that only wrap a single value, the flow returns the inner type directly, e.g. `authorizationStateFlow()` emits `TdApi.AuthorizationState` instances. |
48 | 67 |
|
49 | | -Library provides [extension interfaces](https://tdlibx.github.io/td-ktx/docs/libtd-ktx/kotlinx.telegram.extensions/index.html) to access specific Telegram Object's extensions. This allows you to use the library full potential |
| 68 | +## Calling Telegram functions |
| 69 | +Each TDLib function is exposed as a suspending extension on `TelegramFlow`: |
50 | 70 |
|
51 | | -```Kotlin |
52 | | -class YourTelegramClass : UserKtx { |
53 | | - // Instance of the TelegramFlow connecting extensions to the API |
54 | | - override val api = TelegramFlow() |
55 | | - // Flow that returns updates of the user as a full UserInfo |
56 | | - val fullInfoFlow: Flow<TdApi.UserFullInfo> = api.userFlow().map { user -> |
57 | | - user.getFullInfo() // call TdApi.GetUserFullInfo(userId) with id of the user instance |
58 | | - } |
59 | | -} |
| 71 | +```kotlin |
| 72 | +suspend fun fetchSelf(): TdApi.User = telegramFlow.getMe() |
60 | 73 | ``` |
61 | | -All possible extensions for Telegram entities can be accessed via [TelegramKtx]. List and description of available extension interfaces can be found [here](https://tdlibx.github.io/td-ktx/docs/libtd-ktx/kotlinx.telegram.extensions/index.html) |
62 | 74 |
|
63 | | -[TelegramFlow]: https://tdlibx.github.io/td-ktx/docs/libtd-ktx/kotlinx.telegram.core/-telegram-flow/index.html |
64 | | -[flow extensions]: https://tdlibx.github.io/td-ktx/docs/libtd-ktx/kotlinx.telegram.flows/index.html |
65 | | -[attachClient]: https://tdlibx.github.io/td-ktx/docs/libtd-ktx/kotlinx.telegram.core/-telegram-flow/attach-client.html |
66 | | -[extension functions]: https://tdlibx.github.io/td-ktx/docs/libtd-ktx/kotlinx.telegram.coroutines/index.html |
67 | | -[TelegramKtx]: https://tdlibx.github.io/td-ktx/docs/libtd-ktx/kotlinx.telegram.extensions/-telegram-ktx/index.html |
| 75 | +Explore the full API surface in the [generated docs](https://tdlibx.github.io/td-ktx/docs/libtd-ktx/). |
| 76 | + |
| 77 | +## Samples |
| 78 | +A minimal Compose sample lives in [`sample/app`](sample/app). It wires `TelegramFlow` with Hilt, demonstrates handling the authorization flow, and renders online users with Navigation Compose. |
| 79 | + |
| 80 | +## License |
| 81 | +This project is distributed under the Apache 2.0 License. See [LICENSE](LICENSE) for details. |
0 commit comments