Installation
Add to Cargo.toml
[dependencies]
layer-client = "0.4.5"
tokio = { version = "1", features = ["full"] }
layer-client re-exports everything you need for both user clients and bots.
Getting API credentials
Every Telegram API call requires an api_id (integer) and api_hash (hex string) from your registered app.
Step-by-step:
- Go to https://my.telegram.org and log in with your phone number
- Click API development tools
- Fill in any app name, short name, platform (Desktop), and URL (can be blank)
- Click Create application
- Copy
App api_idandApp api_hash
SECURITY: Never hardcode credentials in source code. Use environment variables or a secrets file that is in
.gitignore.
#![allow(unused)]
fn main() {
// Good — from environment
let api_id: i32 = std::env::var("TG_API_ID")?.parse()?;
let api_hash: String = std::env::var("TG_API_HASH")?;
// Bad — hardcoded in source
let api_id = 12345;
let api_hash = "deadbeef..."; // ← never do this in a public repo
}
Bot token (bots only)
For bots, additionally get a bot token from @BotFather:
- Open Telegram → search
@BotFather→/start - Send
/newbot - Choose a display name (e.g. “My Awesome Bot”)
- Choose a username ending in
bot(e.g.my_awesome_bot) - Copy the token:
1234567890:ABCdefGHIjklMNOpqrSTUvwxYZ
Optional features
SQLite session storage
layer-client = { version = "0.4.5", features = ["sqlite-session"] }
Stores session data in a SQLite database instead of a binary file. More robust for long-running servers.
LibSQL / Turso session storage — New in v0.4.5
layer-client = { version = "0.4.5", features = ["libsql-session"] }
Backed by libsql — supports local embedded databases and remote Turso cloud databases. Ideal for serverless or distributed deployments.
#![allow(unused)]
fn main() {
use layer_client::session_backend::LibSqlBackend;
// Local
let backend = LibSqlBackend::open_local("session.libsql").await?;
// Remote (Turso cloud)
let backend = LibSqlBackend::open_remote(
"libsql://your-db.turso.io",
"your-turso-auth-token",
).await?;
}
String session (portable, no extra deps) — New in v0.4.5
No feature flag needed. Encode a session as a base64 string and restore it anywhere:
#![allow(unused)]
fn main() {
// Export
let s = client.export_session_string().await?;
// Restore
let (client, _shutdown) = Client::with_string_session(
&s, api_id, api_hash,
).await?;
}
See Session Backends for the full guide.
HTML entity parsing
# Built-in hand-rolled HTML parser (no extra deps)
layer-client = { version = "0.4.5", features = ["html"] }
# OR: spec-compliant html5ever tokenizer (overrides built-in)
layer-client = { version = "0.4.5", features = ["html5ever"] }
| Feature | Deps added | Notes |
|---|---|---|
html | none | Fast, minimal, covers common Telegram HTML tags |
html5ever | html5ever | Full spec-compliant tokenizer; use when parsing arbitrary HTML |
Raw type system features (layer-tl-types)
If you use layer-tl-types directly for raw API access:
layer-tl-types = { version = "0.4.5", features = [
"tl-api", # Telegram API types (required)
"tl-mtproto", # Low-level MTProto types
"impl-debug", # Debug trait on all types (default ON)
"impl-from-type", # From<types::T> for enums::E (default ON)
"impl-from-enum", # TryFrom<enums::E> for types::T (default ON)
"name-for-id", # name_for_id(u32) -> Option<&'static str>
"impl-serde", # serde::Serialize / Deserialize
] }
Verifying installation
use layer_tl_types::LAYER;
fn main() {
println!("Using Telegram API Layer {}", LAYER);
// → Using Telegram API Layer 224
}
Platform notes
| Platform | Status | Notes |
|---|---|---|
| Linux x86_64 | ✅ Fully supported | |
| macOS (Apple Silicon + Intel) | ✅ Fully supported | |
| Windows | ✅ Supported | Use WSL2 for best experience |
| Android (Termux) | ✅ Works | Native ARM64 |
| iOS | ⚠️ Untested | No async runtime constraints known |