refactoring, add examples, move to library()

This commit is contained in:
2025-05-21 01:30:48 +02:00
parent c2955b7b1b
commit af71544585
11 changed files with 157 additions and 43 deletions

4
.gitignore vendored
View File

@@ -1,5 +1,5 @@
curl*/
buildDir/
.build/
.cache/
.token
# Prerequisites

View File

@@ -1,6 +0,0 @@
{
"clangd.arguments": [
"--compile-commands-dir=build/"
],
"clangd.path": "clangd",
}

View File

@@ -2,17 +2,50 @@
A minimal C Telegram API Framework
## Requirements
- meson
- libcurl
- json-c
> Note: This project is purely educational. It does not aim to cover the entire Telegram Bot API, but only a selected subset of methods.
### Supported Features
#### Types
## How to build
<details>
<summary>Linux</summary>
```bash
$ meson setup build
$ cd build
$ meson compile
$ meson install
```
</details>
<details>
<summary>Windows</summary>
Install all the required library with `vcpkg` and then copy the DLL file.
```powershell
$ meson setup build --native-file meson-vcpkg.txt
$ cd build
$ meson compile
$ meson install
```
</details>
## Examples
You can find some examples [here](./examples/).
### Supported Types
- **InlineKeyboardMarkup**
- Note: Standard `KeyboardMarkup` is intentionally not supported.
#### Methods
#### Supported Methods
- `getMe`
- `sendMessage`
- `editMessageText`

View File

@@ -0,0 +1,51 @@
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <tgbot.h>
bool run = true;
void sighandler(int signum) {
run = false;
}
void callback(tgbot *bot, tgbot_cbquery *query) {
fprintf(stdout, "Callback called!");
}
void echo_message(tgbot *bot, tgbot_update *update) {
tgbot_send_message(bot, update->chat_id, update->text, "MARKDOWN", NULL, 0, 0);
}
int main(void) {
printf("Running...\n");
/* Retrieve bot's token */
FILE *fp = fopen(".token", "r");
if (fp == NULL) {
fprintf(stderr, "Unable to retrieve bot token\n");
return 1;
}
char token[256];
fscanf(fp, "%s", token);
fprintf(stdout, "Token: %s\n", token);
fclose(fp);
signal(SIGINT, sighandler);
/* Initialize bot */
tgbot bot;
tgbot_init(&bot, token);
tgbot_update update;
while (run) {
tgbot_get_update(&bot, &update, callback);
echo_message(&bot, &update);
}
fprintf(stdout, "Closing...");
tgbot_destroy(&bot);
return 0;
}

View File

@@ -1,11 +1,18 @@
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"
#include "tgbot.h"
#include <tgbot.h>
#define WELCOME_MSG "Hi there! This bot is coded in C."
void parse_command(tgbot *bot, tgbot_update *update);
void sighandler(int signum);
void callback_parser(tgbot *bot, tgbot_cbquery *query);
bool run = true;
tgbot bot;
size_t rows = 1, columns = 2;
tgbot_inlinekeyboardmarkup **keyboard;
@@ -33,11 +40,8 @@ void callback_handler(tgbot *bot, tgbot_cbquery *query) {
}
void sighandler(int signum) {
fprintf(stdout, "Cleaning resources...\n");
tgbot_destroy(&bot);
tgbot_deallocate_inlinekeyboardmarkup(keyboard, rows);
exit(0);
fprintf(stdout, "Closing...\n");
run = false;
}
void parse_command(tgbot *bot, tgbot_update *update) {
@@ -108,7 +112,7 @@ int main(void) {
tgbot_update update;
/* Main loop */
for (;;) {
while (run) {
ret = tgbot_get_update(&bot, &update, callback_handler);
if (ret != TGBOT_OK) {
fprintf(stderr, "tgbot_get_updates()\n");
@@ -119,4 +123,9 @@ int main(void) {
parse_command(&bot, &update);
}
}
tgbot_destroy(&bot);
tgbot_deallocate_inlinekeyboardmarkup(keyboard, rows);
return 0;
}

View File

@@ -1,12 +0,0 @@
#ifndef MAIN_H
#define MAIN_H
#include "tgbot.h"
#define WELCOME_MSG "Hi there! This bot is coded in C."
void parse_command(tgbot *bot, tgbot_update *update);
void sighandler(int signum);
void callback_parser(tgbot *bot, tgbot_cbquery *query);
#endif // MAIN_H

View File

@@ -33,7 +33,6 @@ struct tgbot_me_t {
};
typedef struct tgbot_me_t tgbot_me;
/* TODO: implement variable length string */
/**
* A structure to represent Update object
*/

28
meson-vcpkg.txt Normal file
View File

@@ -0,0 +1,28 @@
[constants]
vcpkg_base_path = 'C:/vcpkg/'
vcpkg_base_install_dir = 'C:/vcpkg/installed/'
vcpkg_target_triplet = 'x64-windows'
vcpkg_host_triplet = 'x64-windows'
vcpkg_installed_dir = vcpkg_base_install_dir + vcpkg_target_triplet + '/'
vcpkg_host_installed_dir = vcpkg_base_install_dir + vcpkg_host_triplet + '/'
vcpkg_toolchain_file = vcpkg_base_path + 'scripts/toolchains/windows.cmake'
[properties]
cmake_toolchain_file = vcpkg_base_path + 'scripts/buildsystems/vcpkg.cmake'
[binaries]
vcpkg = [ vcpkg_base_path + 'vcpkg.exe']
pkgconfig = [ vcpkg_installed_dir + 'tools/pkgconf/pkgconf.exe']
[cmake]
VCPKG_TARGET_TRIPLET = vcpkg_target_triplet
VCPKG_HOST_TRIPLET = vcpkg_host_triplet
VCPKG_CHAINLOAD_TOOLCHAIN_FILE = vcpkg_base_path + 'scripts/toolchains/windows.cmake'
_VCPKG_INSTALLED_DIR = vcpkg_installed_dir
VCPKG_CRT_LINKAGE = 'dynamic'
[built-in options]
pkg_config_path = [ vcpkg_installed_dir + 'lib/pkgconfig;' + vcpkg_installed_dir + 'share/pkgconfig']
cmake_prefix_path = [ vcpkg_installed_dir ]

View File

@@ -1,18 +1,32 @@
project('tgbot', 'c')
cc = meson.get_compiler('c')
project('tgbot', 'c', version: '0.1')
sources = []
subdir('src')
inc_dir = include_directories('include')
deps = []
include_dirs = [inc_dir]
curl_dep = dependency('libcurl')
deps += curl_dep
json_c_dep = dependency('json-c')
deps += json_c_dep
executable('tgbot', sources, include_directories: [include_dirs], dependencies: deps)
deps = [curl_dep, json_c_dep]
install_headers('include/tgbot.h')
#install_subdir('.', install_dir: 'C:/tgbot')
lib = library(
'tgbot',
sources,
dependencies: deps,
include_directories: inc_dir,
install: true,
)
# Example (windows)
lib_inc_dir = include_directories('C:/include')
executable(
'example',
'examples/echobot/echobot.c',
dependencies: deps,
link_with: lib,
include_directories: lib_inc_dir,
win_subsystem: 'console',
)

View File

@@ -1,4 +1,3 @@
sources += files(
'main.c',
'tgbot.c',
)

View File

@@ -5,7 +5,6 @@
#include <stdlib.h>
#include <string.h>
#include "json_object.h"
#include "tgbot.h"
tgbot_rc tgbot_init(tgbot *bot, char *token) {