feat(methods): add sendPhoto
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# tgbot
|
# tgbot
|
||||||
|
|
||||||
A minimal C Telegram API Framework.
|
A minimal C Telegram API library.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ You can find some examples [here](./examples/).
|
|||||||
### Supported Types
|
### Supported Types
|
||||||
|
|
||||||
- **InlineKeyboardMarkup**
|
- **InlineKeyboardMarkup**
|
||||||
- Note: Standard `KeyboardMarkup` is intentionally not supported.
|
- Note: Standard `KeyboardMarkup` is intentionally not supported.
|
||||||
|
|
||||||
#### Supported Methods
|
#### Supported Methods
|
||||||
|
|
||||||
@@ -54,10 +54,10 @@ You can find some examples [here](./examples/).
|
|||||||
- `sendMessage`
|
- `sendMessage`
|
||||||
- `editMessageText`
|
- `editMessageText`
|
||||||
- `sendDice`
|
- `sendDice`
|
||||||
|
- `sendPhoto`
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
- `sendPhoto`
|
|
||||||
- `sendAudio`
|
- `sendAudio`
|
||||||
- `sendDocument`
|
- `sendDocument`
|
||||||
- `sendVideo`
|
- `sendVideo`
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <tgbot/methods.h>
|
||||||
|
#include <tgbot/tgbot.h>
|
||||||
|
#include <tgbot/types.h>
|
||||||
|
|
||||||
|
#define START_MESSAGE "Send /photo to receive a nice landscape!"
|
||||||
|
#define PHOTO_PATH "my_photo.jpg"
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
FILE *tok = fopen(".token", "r");
|
||||||
|
if (!tok) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
char token[512];
|
||||||
|
fscanf(tok, "%s", token);
|
||||||
|
fprintf(stdout, "Token: %s\n", token);
|
||||||
|
|
||||||
|
tgbot_s *bot = tgbot_new(token);
|
||||||
|
if (!bot) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tgbot_update_s update;
|
||||||
|
while (1) {
|
||||||
|
tgbot_get_update(bot, &update, NULL);
|
||||||
|
|
||||||
|
if (!strcmp(update.text, "/start")) {
|
||||||
|
tgbot_send_message(bot, update.chat_id, START_MESSAGE, "MARKDOWN", NULL);
|
||||||
|
} else if (!strcmp(update.text, "/photo")) {
|
||||||
|
tgbot_send_photo(bot, update.chat_id, PHOTO_PATH, "Mountains!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ int tgbot_get_me(const tgbot_s *bot, tgbot_me_s *me);
|
|||||||
int tgbot_send_message(const tgbot_s *bot, int64_t chat_id, const char *text, const char *parse_mode,
|
int tgbot_send_message(const tgbot_s *bot, int64_t chat_id, const char *text, const char *parse_mode,
|
||||||
tgbot_inlinekeyboard_s *reply_markup);
|
tgbot_inlinekeyboard_s *reply_markup);
|
||||||
int tgbot_send_dice(const tgbot_s *bot, int64_t chat_id, const char *emoji);
|
int tgbot_send_dice(const tgbot_s *bot, int64_t chat_id, const char *emoji);
|
||||||
|
int tgbot_send_photo(const tgbot_s *bot, int64_t chat_id, const char *path, const char *caption);
|
||||||
|
|
||||||
/* Updating Methods */
|
/* Updating Methods */
|
||||||
int tgbot_edit_message_text(const tgbot_s *bot, int64_t chat_id, long message_id, const char *text,
|
int tgbot_edit_message_text(const tgbot_s *bot, int64_t chat_id, long message_id, const char *text,
|
||||||
|
|||||||
+2
-4
@@ -58,11 +58,9 @@ if cppcheck.found()
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
# Example
|
# Example
|
||||||
example = executable(
|
executable(
|
||||||
'example',
|
'example',
|
||||||
'examples/inlinekeyboard/inlinekeyboard.c',
|
'examples/sender/sendpic.c',
|
||||||
dependencies: tgbot_dep,
|
dependencies: tgbot_dep,
|
||||||
build_by_default: false,
|
build_by_default: false,
|
||||||
)
|
)
|
||||||
|
|
||||||
test('example_inlinekeyboard', example)
|
|
||||||
+67
-9
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#define opt_size(arr) (sizeof(arr) / sizeof(arr[0]))
|
#define opt_size(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||||
|
|
||||||
static size_t write_callback(const void *ptr, size_t size, size_t nmemb, char *userdata) {
|
static size_t write_callback(void *ptr, size_t size, size_t nmemb, char *userdata) {
|
||||||
size_t real_size = size * nmemb;
|
size_t real_size = size * nmemb;
|
||||||
struct memory_buffer *mem = (struct memory_buffer *)userdata;
|
struct memory_buffer *mem = (struct memory_buffer *)userdata;
|
||||||
|
|
||||||
@@ -53,16 +53,12 @@ static int tgbot_request(const char *url, struct memory_buffer **mb, json_object
|
|||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)write_callback);
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)write_callback);
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, *mb);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, *mb);
|
||||||
} else {
|
} else {
|
||||||
struct memory_buffer *mb_f = malloc(sizeof *mb_f);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, discard_callback);
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, discard_callback);
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, mb_f);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);
|
||||||
if (mb_f) {
|
|
||||||
free(mb_f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
|
||||||
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 30L);
|
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
|
||||||
|
|
||||||
if (json != NULL) {
|
if (json != NULL) {
|
||||||
json_string = json_object_to_json_string_ext(json, JSON_C_TO_STRING_PLAIN);
|
json_string = json_object_to_json_string_ext(json, JSON_C_TO_STRING_PLAIN);
|
||||||
@@ -100,6 +96,60 @@ static int tgbot_execute_method(const tgbot_s *bot, const char *method, tgbot_op
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tgbot_execute_method_multipart(const tgbot_s *bot, const char *method, int64_t chat_id, const char *path,
|
||||||
|
const char *caption) {
|
||||||
|
CURL *curl = curl_easy_init();
|
||||||
|
if (!curl) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char url[URL_LEN] = {0};
|
||||||
|
int chars = snprintf(url, sizeof(url), "%s%s", bot->api, method);
|
||||||
|
if (chars < 0 || (size_t)chars >= sizeof(url)) {
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_mime *mime = curl_mime_init(curl);
|
||||||
|
curl_mimepart *part;
|
||||||
|
|
||||||
|
char chat_id_str[512];
|
||||||
|
snprintf(chat_id_str, sizeof chat_id_str, "%ld", chat_id);
|
||||||
|
|
||||||
|
part = curl_mime_addpart(mime);
|
||||||
|
curl_mime_data(part, chat_id_str, CURL_ZERO_TERMINATED);
|
||||||
|
curl_mime_name(part, "chat_id");
|
||||||
|
|
||||||
|
part = curl_mime_addpart(mime);
|
||||||
|
curl_mime_filedata(part, path);
|
||||||
|
curl_mime_name(part, "photo");
|
||||||
|
|
||||||
|
part = curl_mime_addpart(mime);
|
||||||
|
curl_mime_data(part, caption, CURL_ZERO_TERMINATED);
|
||||||
|
curl_mime_name(part, "caption");
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
|
||||||
|
|
||||||
|
/* Do not print response to output */
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, discard_callback);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);
|
||||||
|
|
||||||
|
CURLcode res = curl_easy_perform(curl);
|
||||||
|
if (res != CURLE_OK) {
|
||||||
|
fprintf(stderr, "curl_easy_perform: %s\n", curl_easy_strerror(res));
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
curl_mime_free(mime);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
curl_mime_free(mime);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int tgbot_get_update(tgbot_s *bot, tgbot_update_s *update, Callback cbq_handler) {
|
int tgbot_get_update(tgbot_s *bot, tgbot_update_s *update, Callback cbq_handler) {
|
||||||
char url[URL_LEN];
|
char url[URL_LEN];
|
||||||
|
|
||||||
@@ -191,10 +241,14 @@ int tgbot_get_me(const tgbot_s *bot, tgbot_me_s *me) {
|
|||||||
|
|
||||||
const json_object *result = json_object_object_get(json, "result");
|
const json_object *result = json_object_object_get(json, "result");
|
||||||
json_object *first_name = json_object_object_get(result, "first_name");
|
json_object *first_name = json_object_object_get(result, "first_name");
|
||||||
snprintf(me->first_name, sizeof(me->first_name), "%s", json_object_get_string(first_name));
|
if (first_name) {
|
||||||
|
snprintf(me->first_name, sizeof(me->first_name), "%s", json_object_get_string(first_name));
|
||||||
|
}
|
||||||
|
|
||||||
json_object *username = json_object_object_get(result, "username");
|
json_object *username = json_object_object_get(result, "username");
|
||||||
snprintf(me->username, sizeof(me->username), "%s", json_object_get_string(username));
|
if (username) {
|
||||||
|
snprintf(me->username, sizeof(me->username), "%s", json_object_get_string(username));
|
||||||
|
}
|
||||||
|
|
||||||
json_object_put(json);
|
json_object_put(json);
|
||||||
|
|
||||||
@@ -233,3 +287,7 @@ int tgbot_send_dice(const tgbot_s *bot, int64_t chat_id, const char *emoji) {
|
|||||||
|
|
||||||
return tgbot_execute_method(bot, "sendDice", options, opt_size(options));
|
return tgbot_execute_method(bot, "sendDice", options, opt_size(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tgbot_send_photo(const tgbot_s *bot, int64_t chat_id, const char *path, const char *caption) {
|
||||||
|
return tgbot_execute_method_multipart(bot, "sendPhoto", chat_id, path, caption);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user