tgbot-cpp is a C++20 library that covers the Telegram Bot API
C++ library for Telegram bot API
At a glance
- What is it?
- tgbot-cpp is a C++ library for the Telegram Bot API, currently tracking version 10.3, with the API types generated from the published schema and a Makefile driven build that works with Conan 2, CMake and Docker. The example programs cover long polling, webhooks, custom curl, keyboards and file transfer, and the library is MIT licensed.
- Who is it for?
- Adopt tgbot-cpp when you are writing a Telegram bot in C++ and want the API surface generated and kept in step with the schema rather than hand written. Do not adopt it if your bot is anything other than long lived, because a polling bot holds a process open, and the library offers no scheduling of its own.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 38 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A library, and a version line that tracks the API
tgbot-cpp is a C++ library for the Telegram bot API, and the readme is short, which is appropriate for a library whose value is in the API surface rather than in a design philosophy.
The State section has one line in it, a checked box for Telegram Bot API 10.3. That is the whole status report, and it is the most important number in the readme, because the value of a generated client library is entirely in how closely it tracks the published API.
The release history is regular. v1.13 was published on 2026-09-14, v1.12.3 on 2026-08-12 and v1.12.2 on 2026-08-05, and the last push was on 2026-09-14. So the project is active, and the version number moves with the Bot API rather than with a marketing cycle.
The implementation is C++ and the licence is MIT, with the LICENSE file at the root of the repository. The documentation is published separately at reo7sp.github.io/tgbot-cpp, and the coverage badge points at coveralls, so the tests are measured and published.
The topics are exactly what you would expect for a focused library, bot, cpp, telegram, telegram-api and telegram-bot, and there is no sign of the project trying to be a framework.
The echo bot shows the event model in thirty lines
The example is a simple echo bot which sends everything it receives, and it is worth reading in full because it is the whole API in one function.
bot.getEvents().onAnyMessage([&bot](std::shared_ptr<TgBot::Message> message) {
const auto text = message->text.value_or("");
std::cout << "User wrote " << text << std::endl;
if (text.starts_with("/start")) {
return;
}
bot.getApi().sendMessage(message->chat->id, "Your message is: " + text);
});Three things are visible. The bot is constructed with a token, the events are registered through getEvents() with a callback that takes a shared pointer to a message, and the API calls go through getApi().
The shared pointer is the notable design choice. A Telegram message is a graph rather than a struct, with a chat, a user and possibly a reply chain, and handing it around as a shared pointer avoids copying that graph for every handler. It also means the message stays alive while a handler is working, which matters for the asynchronous API calls underneath.
The value_or calls are the other detail. The optional fields on a message are genuinely optional, and the library models them as std::optional, so reading message->text without checking gives you an empty string rather than a crash. A bot that handles text from any source can therefore treat every message the same way.
The rest of the example registers an onCommand handler, prints the bot username from getMe, and then runs a TgLongPoll in a loop, with the whole thing wrapped in a try block that catches TgBot::TgException and prints the message.
Ten examples cover the ways a bot actually receives updates
The examples directory is the documentation of how the library is used in practice, and the ten entries are the use cases rather than the API surface.
There is echobot, the simple one, and echobot-proxy for proxy usage, echobot-webhook-server for running behind a webhook, and echobot-setmycommands for command configuration. Then there is inline-keyboard and reply-keyboard, photo, receive-file and received-text-processing.
That list maps onto the three ways a bot receives updates, which is the axis that actually matters. Long polling is the simplest and is what the example in the readme uses. A webhook server is what you need when the bot is behind a reverse proxy and you do not want an open connection. And a custom curl client is there for the case where you have to control the HTTP client, since the library is built on libcurl and a custom client lets you set the options the library does not expose.
The examples are also how you build. The readme shows a local install and a single example build.
make install INSTALL_PREFIX=build/install
make example EXAMPLE=echobot INSTALL_PREFIX=build/install
TOKEN=... ./build/Release/examples/echobot/echobotThe make examples target builds all of them, and there is a Docker path as well, with make docker-run-example for one and a Compose path for all of them at once, which needs an env file copied from env.example and filled in.
Consuming it from CMake
The usage section covers the two ways to depend on the library, and it is short enough that the choice is obvious.
For an installed package, you add it to your CMakeLists.txt.
find_package(TgBot CONFIG REQUIRED)
target_link_libraries(your_bot PRIVATE TgBot::TgBot)So the library installs a CMake package configuration and exports a single imported target, TgBot::TgBot, and a consumer links that one name rather than a path and a set of libraries. That is the modern convention, and it means the transitive dependencies come along with the target.
The alternative is to add the repository directly with add_subdirectory, which the readme points at for the case where it is included as a Git submodule, and there is a submodule example in the examples directory to match.
For Docker, the image reo7sp/tgbot-cpp on Docker Hub can be used as the base image, which means a containerised bot can start from a layer that already has the library built and installed.
One point about the build system is worth flagging for anyone on Windows, and it is in the Makefile rather than the readme. When the OS is Windows_NT, the CMake generator is forced to Ninja and the Conan build arguments are amended to select it, and the documentation says to run the Makefile targets from Git Bash. So the Makefile is the entry point on every platform, and on Windows it is run from a Unix-like shell.
Conan 2 brings Boost, nlohmann/json, libcurl and GoogleTest
The dependency section is where the design of the library becomes concrete.
Required to build the library are a C++20 compiler, CMake 3.16 or newer, Conan 2 and Make. Additionally required for code generation are Python and Poetry.
Conan installs the library dependencies: Boost, nlohmann/json, libcurl, and GoogleTest when tests are enabled, and the readme notes that these libraries do not need to be installed separately.
So the library does its own HTTP with libcurl, its own JSON with nlohmann/json, and it uses Boost for the parts of the standard library that C++20 does not yet have or that a library like this prefers not to depend on the standard library for. Conan 2 rather than a system package manager means the dependency versions are pinned by a recipe, and the same set works on Linux, macOS and Windows without the user resolving them by hand.
The installation instructions are given per platform, and they are the real setup cost. On Debian and Ubuntu you install the build tools and a specific Conan release, pinned to version 2.31.2 in the commands, downloading the .deb for your architecture. On macOS it is Homebrew, with cmake and conan. On Windows it is a sequence of winget installs for Git, GnuWin32 Make, CMake, Ninja and Visual Studio with the native desktop workload, then the Conan installer fetched and run through PowerShell.
The development extras are the same everywhere: Python, Poetry and clang-format, installed with pipx on Linux and macOS and with pipx on Windows too, and the Windows one pins clang-format to a version of at least 22.1.8.
The API types are generated from a downloaded schema
The part of the repository that explains the release cadence is the code generation.
The pyproject file at the root describes a separate project, tgbot-cpp-codegen, described as a Telegram Bot API schema downloader and C++ code generator. It is a Poetry project with Python 3.10 or newer, and its dependencies are pyyaml, jinja2 for the templates, pytest and pytest-cov for the tests, ruff for the linting, and tgbotspec at 0.2.4, which is the package that knows how to fetch and parse the published API specification.
So the types in the library are not hand written. The schema is downloaded, rendered through Jinja templates into C++ headers, and committed, and the HOW_TO_UPDATE_TELEGRAM_API.md document describes the procedure.
The Makefile shows the wiring. There is an api-gene... target, an api-update target, and the generated files are named explicitly, with API_METHODS_CPP pointing at src/ApiMethods.cpp and API_METHODS_INC at include/tgbot/ApiMethods.inc.h, plus a separate clang-format configuration for the generated methods. The CPP_FILES variable deliberately excludes the generated .inc.h files and the generated source, so a formatting or linting pass does not rewrite machine produced code.
That is the right arrangement for a client library whose API changes on the schedule of somebody else's documentation, and it explains why the version numbers move as often as they do.
Make targets, sanitizers and a multi-stage image
The development checks are exposed through the Makefile, and they are three commands.
make format
make lint
make testOr the same thing in a container, with make docker-test.
The Makefile is long, and the variables at the top tell you what the project is capable of. There is ENABLE_SANITIZERS, defaulting to OFF, and ENABLE_COVERAGE, also defaulting to OFF, so the project supports building with sanitizers and with coverage instrumentation rather than treating them as an afterthought. There is a separate build type defaulting to Release, and CONAN_BUILD_ARGS defaulting to --build=missing, which is the flag that lets Conan build the missing dependencies from source instead of requiring a binary for every platform.
The targets themselves are split into variants, and the split tells you how the CI is arranged. There is configure, configure-with-system and configure-with-test, and the same three for build, and then install, install-with-system and install-only. The with-system variants are the ones that use the system libraries rather than the Conan ones, which is how the Docker image is built, and the with-test variants add GoogleTest.
The Dockerfile is a three stage build on debian:trixie. A dependencies stage installs build-essential, cmake, libboost-dev, libcurl4-openssl-dev and nlohmann-json3-dev, a builder stage copies the source in and runs make install-with-system with a DESTDIR, and a runtime stage copies the installed tree into /usr. The Dockerfile_test variant and docker-compose.test.yaml cover the test matrix, and there is a conan-center/ directory for the recipe used by the Conan Center, plus HOW_TO_RELEASE.md for the release process.
Editorial conclusion
Adopt tgbot-cpp when you are writing a Telegram bot in C++ and want the API surface generated and kept in step with the schema rather than hand written. Do not adopt it if your bot is anything other than long lived, because a polling bot holds a process open, and the library offers no scheduling of its own. Verify first which Bot API version you need against the state line in the readme, that your compiler supports C++20, and that you can run the code generation step, because the API types in the source tree are produced from a downloaded schema and drift is otherwise invisible.
Frequently asked questions
What is tgbot-cpp?
It is a C++ library for the Telegram bot API, currently tracking Telegram Bot API 10.3, with a high-level event API, long polling and webhook support, and a generated API surface. It is MIT licensed.
How do I use tgbot-cpp in my CMake project?
For an installed package, find_package(TgBot CONFIG REQUIRED) and link the imported target with target_link_libraries(your_bot PRIVATE TgBot::TgBot). The repository can also be added with add_subdirectory, for example when it is included as a Git submodule.
What do I need to build tgbot-cpp?
A C++20 compiler, CMake 3.16 or newer, Conan 2 and Make, plus Python and Poetry for the code generation. Conan installs the dependencies, which are Boost, nlohmann/json, libcurl and GoogleTest when the tests are enabled.
How are the Telegram API types kept up to date?
They are generated. The repository includes a separate Python project, tgbot-cpp-codegen, that downloads the Bot API schema with the tgbotspec package and renders it through Jinja templates into the C++ sources, and HOW_TO_UPDATE_TELEGRAM_API.md documents the procedure.
What examples does the project ship?
Ten of them, including a simple echo bot, a proxy example, a webhook server, command configuration, inline and reply keyboards, photo handling, file receiving and text processing. The readme also shows how to build one locally with make example and how to run everything in Docker.
Does tgbot-cpp support long polling and webhooks?
Yes. The readme example uses a TgLongPoll in a startLoop, and the examples directory contains a webhook server example as well, alongside a proxy example and a custom curl client example.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/reo7sp-tgbot-cpp)Was this useful?