Skip to content

ndmik-dev/tdlib-poc

Repository files navigation

tdlib-poc

POC project for integrating TDLib with a Spring Boot Java application.

Project

  • Group: io.ndmik
  • App name: tdlib-poc
  • Stack: Java + Spring Boot + TDLib

Goals

  • Implement Telegram authorization flow via TDLib.
  • Fetch current user profile (getMe).
  • Send a plain text message to a target chat/user.

Scope

  • This repository is focused on a minimal, testable integration POC.
  • Detailed execution checklist is tracked in POC_PLAN.md.
  • Architecture notes and flow diagram are in ARCHITECTURE.md.

Instructions

  1. Build TDLib on your machine and keep libtdjson + td_json_client.h available.
  2. Place the native TDLib library in the project native/ directory.
  3. Configure TDLib environment variables:
    • TD_ENABLED=true
    • Optional: TD_USE_TEST_DC=true (for Telegram test DC)
    • TD_API_ID
    • TD_API_HASH
    • TD_PHONE
    • Optional: TD_DB_DIR, TD_FILES_DIR, TD_NATIVE_LIB_NAME, TD_NATIVE_LIB_PATH
  4. Run the application from project root:
    • ./gradlew bootRun
  5. When native loading is wired, run with Java library path pointing to native/:
    • ./gradlew bootRun -Djava.library.path=./native
  6. Follow the POC checklist in POC_PLAN.md to complete auth, getMe, and message send flow.

Auth Flow Endpoints

  • GET /api/auth/status - current TDLib authorization state.
  • POST /api/auth/phone - submit phone number:
    • body: { "phoneNumber": "+1234567890" }
  • POST /api/auth/code - submit login code:
    • body: { "code": "12345" }

Phase 5 Endpoints

  • GET /api/td/me - fetch current authorized user (getMe).
  • POST /api/td/messages/send - send plain text message:
    • body: { "chatId": 123456789, "text": "hello from tdlib-poc" }
  • GET /api/td/chats?limit=50 - list known TDLib chat IDs.
  • GET /api/td/chats/{chatId} - get chat details by TDLib chat ID.
  • POST /api/td/chats/search-public - resolve public chat/group by username:
    • body: { "username": "group_or_channel_username" }

Quick Test Flow

  1. Complete auth until status is READY:
    • curl -s http://localhost:8080/api/auth/status
  2. Resolve a valid TDLib chat ID:
    • curl -s -X POST http://localhost:8080/api/td/chats/search-public -H "Content-Type: application/json" -d '{"username":"your_group_username"}'
    • or curl -s "http://localhost:8080/api/td/chats?limit=50" and inspect chat_ids
  3. Fetch current user:
    • curl -s http://localhost:8080/api/td/me
  4. Send message using TDLib chat.id:
    • curl -s -X POST http://localhost:8080/api/td/messages/send -H "Content-Type: application/json" -d '{"chatId":123456789,"text":"hello from tdlib-poc"}'

HTTPie Test Script

  • Script: httpie-requests.sh
  • Supports:
    • auth status check
    • phone/code flow (with hidden code input prompt)
    • getMe
    • chat id resolution by PUBLIC_CHAT_USERNAME
    • interactive chat selection from /api/td/chats
    • send message

Examples:

  • interactive:
    • bash ./httpie-requests.sh
  • resolve by public username:
    • PUBLIC_CHAT_USERNAME=group_username bash ./httpie-requests.sh
  • direct chat id:
    • CHAT_ID=123456789 bash ./httpie-requests.sh

Run Scripts

  • Local run:
    • ./run-local.sh
  • Run with TDLib enabled and native path:
    • TD_API_ID=... TD_API_HASH=... TD_PHONE=... ./run-with-native-lib.sh
  • Smoke test (getMe + send message):
    • CHAT_ID=123456789 ./smoke-test.sh
  • Final sign-off automation (smoke + optional restart/session reuse):
    • CHAT_ID=123456789 ./final-signoff.sh
    • optional: MANAGE_APP=false to run against already running app

Release Prep

  • Environment template:
    • .env.example
  • Release checklist:
    • RELEASE_CHECKLIST.md

Troubleshooting

  • TD_API_ID and TD_API_HASH must be set:
    • ensure vars are present in the same shell that starts the app.
  • Chat not found:
    • use TDLib chat id from /api/td/chats or /api/td/chats/search-public.
  • No chats returned:
    • open/join target chat in Telegram with same account, then retry.
  • Can't lock file ... td.binlog:
    • another process uses .tdlib/db; stop the other app instance.
  • Username resolution fails:
    • searchPublicChat works only for public usernames, not private group titles.

Final Sign-off Checklist

  • Auth reaches READY.
  • /api/td/me returns current user.
  • /api/td/messages/send succeeds with TDLib chat id.
  • App restart keeps TDLib session (no re-login required).
  • ./gradlew test passes.

Automated variant:

  • CHAT_ID=123456789 ./final-signoff.sh

Current State

  • Phase 1: completed
  • Phase 2: completed
  • Phase 3: completed
  • Phase 4: completed
  • Phase 5: completed
  • Phase 6: completed
  • Build validation: ./gradlew test passed

Phase 6 Notes

  • Structured TDLib auth/client lifecycle logs are enabled (event=... format).
  • Sensitive values in surfaced auth errors are redacted.
  • Update loop uses retry with bounded exponential backoff on failures.
  • Shutdown now drains/stops auth loop and pending TDLib response futures gracefully.

Phase 7 Tests

  • Added unit tests:
    • src/test/java/io/ndmik/tdlibpoc/tdlib/TdJsonCodecTests.java
    • src/test/java/io/ndmik/tdlibpoc/tdlib/auth/TdAuthorizationStateTests.java
    • src/test/java/io/ndmik/tdlibpoc/tdlib/auth/TdlibAuthServiceTests.java
  • Added gated native smoke test:
    • src/test/java/io/ndmik/tdlibpoc/tdlib/TdClientNativeLoadSmokeTests.java
    • runs only when TD_NATIVE_SMOKE=true

Run all tests:

  • ./gradlew test

Run native smoke test explicitly:

  • TD_NATIVE_SMOKE=true TD_NATIVE_LIB_PATH=./native ./gradlew test --tests "*TdClientNativeLoadSmokeTests"

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published