Library for Telegram Bot Api written in C++
Compiler with C++17 support
CMake v 3.5 or higher
Conan
Python 3.x.x
API for this library generated automatically (if use Conan) during the build
If you want to update API just rebuild the library as usual
If you choose building by hands, to generate API you need the following python libraries:
lxml
html2markdown
beautifulsoup4
requests
Python 3 and pip3 is required for automatic API generation, so make sure you have added it to your PATH (e.g it can be run from terminal without specifying path explicitly)
conan remote add <some_name> https://api.bintray.com/conan/yehorka9991/magic_get
This will add repository with library recipe to your remotes or download conanfile.py
from this repo and run
cd /path/to/conanfile
conan create .
conan run .
Then you can add library by adding
if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake")
message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
file(DOWNLOAD "https://github.com/conan-io/cmake-conan/raw/v0.15/conan.cmake"
"${CMAKE_BINARY_DIR}/conan.cmake")
endif()
include(${CMAKE_BINARY_DIR}/conan.cmake)
conan_cmake_run(REQUIRES tglib/0.1@yehorka/stable
BASIC_SETUP
BUILD missing)
add_executable (${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
You can add the following to your existing conanfile.txt
[requires]
tglib/0.1@yehorka/stable
See more detailed information here https://github.com/conan-io/cmake-conan
Now you can copy and run examples from /examples
folder.
Tests are run automatically. If you dont want to run the tests set "build_tests"
option to false. You can do this in your conanfile.txt
[options]
tglib::build_tests = False
Or add modify code above
conan_cmake_run(REQUIRES tglib/0.1@yehorka/stable
BASIC_SETUP
BUILD missing
OPTIONS tglib:build_tests=False)
By default spdlog is used. You can replace it by user-defined logger by calling
utility::Logger::set_implementation(your_logger_obj)
in C++ code.
Your logger implementation should inherit LoggerBase
class and implement all virtual functions.
Logger has three levels of verbosity:
- 0 - no logging enabled
- 1 - only warnings or errors
- 2 - warnings, errors and additional information about executing functions and received results
By default 1 level is used. You can change it by specifying verbosity_level
variable in conan build
or VERBOSITY_LEVEL
in CMakeLists.txt if you choosed manual building.
Example of how your conanfile.txt may look like
[requires]
tglib/0.1
[generators]
cmake
[options]
tglib:verbosity_level=2
tglib:build_tests=False
There are some examples of bots in examples
folder.
#include <telegram_bot.h>
struct User {
std::string username;
std::string password;
std::string date_of_birth;
std::string to_string() {
std::string buffer;
buffer.reserve(username.size()+password.size()+date_of_birth.size());
buffer += "\nName: " + username +
"\nPassword: " + password +
"\nBirth date: " + date_of_birth + '\n';
return buffer;
}
};
int main() {
using namespace telegram;
Bot bot{BOT_TOKEN};
bot.onMessage("/register",[&](const Message& msg){
bot.sendMessage(msg.chat.id,"Send your username",ParseMode::Markdown);
auto registration = std::make_shared<Sequence<MessageCallback>>();
auto user = std::make_shared<::User>();
// transition is an action that bot will do after each step
// check is a function that is called BEFORE next step
// and must return boolean value, and indicates
// if value should be passed to next step or not
registration->addTransition([user,&bot](const Message& m){
user->username = m.text.value();
bot.reply(m,"Send your password");
})->addCheck([&](const Message& m){
if (!m.text || m.text->size() < 3) {
bot.reply(m,"Username is empty or too short");
return false;
}
return true; // must always return boolean value
// if value is false - current step is repeated
})->addTransition([user,&bot](const Message& m){
user->password = m.text.value();
bot.reply(m,"Send your date of birth");
})->addCheck([&](const Message& m){
if (!m.text || m.text->size() < 3) {
bot.reply(m,"Password cannot be empty!");
return false;
}
return true;
})->addTransition([user,&bot](const Message& m){
user->date_of_birth = m.text.value();
bot.sendMessage(m.chat.id,user->to_string());
})->addCheck([&bot,user](const Message& m){
if (!m.text || m.text->size() < 3) {
bot.reply(m,"Date of birth must not be empty.");
return false;
}
return true;
});
// you can add a check that will be used to every step
registration->addCommonCheck([&](const Message& m){
if (m.text->find("/stop") != std::string::npos){
bot.reply(m,"Registration cancelled");
bot.stopSequence(m.chat.id);
return false;
};
return true;
});
registration->onExit([&,user](const Message& ){
// Database::write(user); // do something with user object
});
// add sequence to bot
bot.startSequence(msg.from->id,registration);
});
bot.start(100);
}
#include <telegram_bot.h>
int main() {
using namespace telegram;
Bot bot{BOT_TOKEN};
// or you can you bot.onMessage()
bot.onEvent<MessageCallback>("/start",[&](const Message& m){
bot.sendMessage(m.chat.id,"This is bot that can reply to some commands.");
});
bot.onEvent<MessageCallback>("/help",[&](const Message& m){
bot.sendMessage(m.chat.id,"List of allowed commands:\n\t/help\n\t/start\n\t/number\n");
});
bot.onEvent<MessageCallback>("/number",[&](const Message& m){
bot.sendMessage(m.chat.id,std::to_string(rand() % 150));
});
// regexes have the lowest priority
// so the bot will respons this callback if and only
// if it will not match any callback or command
bot.onEvent<MessageCallback>(std::regex{"(.*)"},[&](const Message& m){
bot.sendMessage(m.chat.id,"Command is not supported. See list of supported commantd /h");
});
bot.setMyCommands({{"/start","get bot description"},
{"/help","get list of allowed commands"},
{"/number","get random number"}});
// you can use regexes for any <callback>Callback signature;
bot.start(100);
}
See more in examples
folder.
To generate documentation for project use doxygen
cd /path/to/project
doxygen Doxyfile
If you experience any bug or shortcoming, please leave an issue on GitHub or contact me on Telegram (@Malbu0698)
The project is under MIT license so it is free for usage.