A modern, high-performance Telegram client framework for C++20 built on top of TDLib.
CppGram brings the developer experience of Pyrogram and Telethon to the C++ ecosystem while maintaining performance, type safety, and scalability.
- User account login with phone number
- Bot account login with BotFather token
- OTP verification via callback
- Two-factor authentication (2FA)
- Automatic session persistence via TDLib
- Send, edit, delete, forward messages
- Reply to messages
- Pin / unpin messages
- Reactions (emoji)
- Message search (global and per-chat)
- Send photos, videos, documents, audio, voice notes, video notes, animations, stickers
- Media metadata extraction (dimensions, duration, file size, thumbnails)
- File download with progress callback
- Polls (regular and quiz mode)
- Dice
- Contacts
- Locations (including live location)
- Venues
- Inline keyboard buttons (callback data, URLs, switch inline)
- Reply keyboards
- Remove keyboard / force reply
- Callback query handling and answering
- Create groups, supergroups, channels
- Set title, description, photo, permissions
- Ban, unban, restrict, promote members
- Get member list, count, administrators
- Generate invite links
- Join / leave chats
- Get user info and profile
- Block / unblock users
- New messages (
onMessage) - Edited messages (
onEditedMessage) - Deleted messages (
onDeletedMessages) - Callback queries (
onCallbackQuery)
- Chat type:
privateChat(),group(),channel() - Content:
text(),media(),photo(),video(),document(),audio(),voice(),sticker(),animation(),pollMsg(),locationMsg(),contactMsg(),dice() - Message state:
incoming(),outgoing(),reply(),forwarded(),bot() - Targeting:
command("name"),chatId(id),userId(id),regex("pattern") - Composable:
Filters::text() && Filters::privateChat() && !Filters::bot()
- Pyrogram-inspired API
- Modern C++20
- Composable filter system with
&&,||,! - Entity methods (
msg.reply(),msg.pin(),chat.banMember()) - Builder-style keyboard construction
- Event-driven architecture
- Cross-platform (Linux, macOS, Windows)
Application
│
▼
CppGram API (Client)
│
▼
Event Dispatcher (handlers, filters)
│
▼
TDLib Adapter (async request/response)
│
▼
TDLib
│
▼
Telegram Servers
- C++20 compiler (GCC 12+, Clang 15+, MSVC 2022+)
- CMake 3.21+
- OpenSSL
- zlib
- SQLite3 (optional)
git clone https://github.com/your-org/cppgram.git
cd cppgram
mkdir build && cd build
cmake ..
cmake --build . --config ReleaseTDLib is fetched automatically via CMake FetchContent (pinned to a specific version).
- Visit my.telegram.org
- Log in and create an application
- Note your
api_idandapi_hash
#include <cppgram/client.hpp>
using namespace cppgram;
int main() {
Client client(API_ID, "API_HASH");
client.loginBot("BOT_TOKEN");
client.run();
}Client client(API_ID, "API_HASH");
client.login("+1234567890",
[]() -> std::string {
std::string code;
std::cout << "Enter OTP: ";
std::cin >> code;
return code;
},
[]() -> std::string {
std::string pw;
std::cout << "Enter 2FA password: ";
std::cin >> pw;
return pw;
}
);// Handle all text messages
client.onMessage(
Filters::text(),
[](Message msg) {
std::cout << msg.sender.username << ": " << msg.text << "\n";
}
);
// Handle commands
client.onMessage(
Filters::command("ping"),
[](Message msg) {
msg.reply("pong");
}
);
// Compose filters
client.onMessage(
Filters::text() && Filters::privateChat() && !Filters::bot(),
[](Message msg) {
msg.reply("Hello, " + msg.sender.first_name + "!");
}
);client.onMessage(
Filters::command("menu"),
[](Message msg) {
InlineKeyboard kb;
kb.addButton(0, InlineKeyboardButton::callback("Option A", "a"));
kb.addButton(0, InlineKeyboardButton::callback("Option B", "b"));
kb.addButton(1, InlineKeyboardButton::link("Website", "https://example.com"));
msg.reply("Choose:", kb);
}
);
client.onCallbackQuery([](CallbackQuery q) {
q.answer("You chose: " + q.data);
});client.sendPhoto(chat_id, InputFile::local("image.jpg"), "My photo");
client.sendDocument(chat_id, InputFile::local("report.pdf"), "Q4 Report");
client.sendVideo(chat_id, InputFile::local("clip.mp4"));
client.sendSticker(chat_id, InputFile::local("sticker.webp"));client.sendPoll(chat_id, "Favorite language?", {"C++", "Rust", "Python"});
// Quiz mode
PollConfig quiz;
quiz.type = PollType::Quiz;
quiz.correct_option_id = 0;
quiz.explanation = "C++ is the best!";
client.sendPoll(chat_id, "What is CppGram written in?", {"C++", "Python"}, quiz);auto chat = client.getChat(chat_id);
chat.setTitle("New Title");
chat.setDescription("Updated description");
chat.banMember(user_id);
ChatAdminRights rights;
rights.can_delete_messages = true;
rights.can_pin_messages = true;
chat.promoteMember(user_id, rights);cppgram/
├── include/cppgram/
│ ├── client.hpp # Main client class
│ ├── message.hpp # Message entity
│ ├── chat.hpp # Chat entity + ChatMember
│ ├── user.hpp # User entity
│ ├── types.hpp # Core types, enums, structs
│ ├── media.hpp # Media types (Photo, Video, etc.)
│ ├── keyboard.hpp # Inline/reply keyboard types
│ ├── callback_query.hpp # Callback query type
│ ├── filters.hpp # MessageFilter + Filters namespace
│ ├── handlers.hpp # Handler structs
│ ├── i_backend.hpp # Backend interface
│ ├── errors.hpp # Exception hierarchy
│ ├── result.hpp # Result<T> type
│ └── log.hpp # Logger
├── src/
│ ├── backend/
│ │ ├── client.cpp # ClientImpl (TDLib integration)
│ │ ├── tdlib_adapter.hpp
│ │ ├── td_conversions.hpp
│ │ └── log.cpp
│ └── core/
│ ├── entities.cpp # Entity methods
│ └── filters.cpp # Filter implementations
├── tests/
├── examples/
└── CMakeLists.txt
- TDLib integration
- Authentication (user + bot)
- Text messaging (send, edit, delete, forward, pin)
- Media messaging (photo, video, document, audio, voice, sticker, animation)
- Rich messages (polls, dice, contacts, locations, venues)
- Inline keyboards + callback queries
- Chat management (create, permissions, ban/restrict/promote)
- Composable filter system
- Event handlers (messages, edits, deletes, callbacks)
- File download
- Message search
- Async coroutines (C++20 co_await)
- Session storage with SQLite
- Profile photo management
- Scheduled messages
- Message formatting (bold, italic, code, links)
- Plugin system
- Forum/topic support
- Stories
- Performance optimizations
- Stable API
- Full documentation
- Production-ready release
Contributions are welcome.
Before contributing:
- Run
clang-formaton your code - Run
ctestto verify tests pass
All pull requests must pass CI checks.
MIT License
Copyright (c) 2026 CppGram Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files to deal in the Software without restriction.