Простой Telegrambot на СИ
Здравствуйте.
В статье представлен код простого телеграмбота, который можно установить на любой линукс-компьютер или роутер. Бот работает через getUpdates, то есть без вебхука.
На устройство нужно установить libopenssl, curl и сертификаты. Если ставите бота на роутер, то чтобы его не загромождать, создайте файл — /etc/ssl/certs/Go_Daddy_Class_2_CA.crt, вот с таким содержимым…
Содержимое
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----
Код бота
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#define BOT_ADDRESS "https://api.telegram.org/bot803596633:f1thviAAEnIIWOo6zdVcp6wwhQ5-km3UsoY" // тута ваш токен
#define GET_METHOD_READ_SIZE 128
#define GET_METHOD_WRITE_SIZE 128
typedef struct {
size_t size;
char *text;
} json_message;
//////////////////////////// здесь принимаются сообщения //////////////////////////
size_t read_message(void *raw_message, size_t size, size_t nmemb, void *dest)
{
size_t real_size = size * nmemb;
json_message* dest_message = (json_message*) dest;
dest_message->text = realloc(dest_message->text, dest_message->size + real_size + 1);
if(dest_message->text == NULL)
{
printf("Error: Маловато памяти.\n");
return 0;
}
memcpy(&(dest_message->text[dest_message->size]), raw_message, real_size);
dest_message->size += real_size;
dest_message->text[dest_message->size] = '\0';
return real_size;
}
///////////////////// функция нужна curl`у для отправки сообщений/////////////////////
size_t emp_function(void *no_use, size_t size, size_t nmemb, void *null)
{
no_use = no_use; null = null;
return size * nmemb;
}
//////////////////////////// здесь отправляются сообщения //////////////////////////
void sendMessage(char *chat_id)
{
int result;
char GET_write[GET_METHOD_WRITE_SIZE] = {0,};
snprintf(GET_write, GET_METHOD_WRITE_SIZE - 1, "%s/sendMessage?chat_id=%s&text=Reciv 'w' OK!", BOT_ADDRESS, chat_id); // если отправляете что-то длинное, то увеличить GET_METHOD_WRITE_SIZE
printf("LenGET_write:%d_END\n", (int)strlen(GET_write));
CURL *write_handle = curl_easy_init();
curl_easy_setopt(write_handle, CURLOPT_URL, GET_write);
curl_easy_setopt(write_handle, CURLOPT_WRITEFUNCTION, emp_function);
curl_easy_setopt(write_handle, CURLOPT_READDATA, NULL);
result = curl_easy_perform(write_handle);
curl_easy_cleanup(write_handle);
if(result != 0) printf("\nError cURL_2:%d\n", result);
}
///////////////////////////////////////////////////////////////////////////////////
int main()
{
int result;
json_message in_message = {0, NULL};
unsigned long update_id = 0;
curl_global_init(CURL_GLOBAL_ALL);
char GET_read[GET_METHOD_READ_SIZE] = {0,};
printf("START\n");
while (1)
{
in_message.text = (char*)malloc(1 * sizeof(char));
in_message.text[0] = '\0';
snprintf(GET_read, GET_METHOD_READ_SIZE - 1, "%s/getUpdates?limit=1&offset=%lu&timeout=10", BOT_ADDRESS, update_id); // обновления каждые 10 секунд (timeout=10)
CURL *read_handle = curl_easy_init();
curl_easy_setopt(read_handle, CURLOPT_URL, GET_read);
curl_easy_setopt(read_handle, CURLOPT_WRITEFUNCTION, read_message);
curl_easy_setopt(read_handle, CURLOPT_WRITEDATA, &in_message);
result = curl_easy_perform(read_handle);
curl_easy_cleanup(read_handle);
if(result != 0) printf("\nError cURL_1:%d\n", result);
update_id = 0;
/////////////////////////// read update_id ///////////////////////////////
char *p = NULL;
if((p = strstr(in_message.text, "update_id\":")) != NULL)
{
update_id = strtoul(p + 11, NULL, 0);
printf("MYupdate_id:%lu_END\n\n", update_id);
}
if(update_id != 0) update_id++;
/////////////////////////// read chat_id ///////////////////////////////
char chat_id[16] = {0,};
if((p = strstr(in_message.text, "chat\":{\"id\":")) != NULL)
{
memccpy(chat_id, p + 12, ',', 15);
chat_id[strlen(chat_id) - 1] = 0;
}
printf("MYChat_id:%s_END\n", chat_id);
//////////////////////////// read msag ////////////////////////////////
char msg_text[16] = {0,}; // если будут приходить сообщения длинней 15 симв., тогда увеличить буфер. Ну или калок/малок-реалок)))
if((p = strstr(in_message.text, "text\":\"")) != NULL)
{
memccpy(msg_text, p + 7, '"', 15);
msg_text[strlen(msg_text) - 1] = 0;
}
printf("Msg_text:%s_END\n", msg_text);
in_message.size = 0;
free(in_message.text);
///////////////////////////// my functions ////////////////////////////////
if(strstr(msg_text, "w") != NULL)
{
sendMessage(chat_id);
}
else if(strstr(msg_text, "/start") != NULL)
{
printf("Кто-то нашёл бота.\n");
}
else printf("NO_DATA\n");
}
curl_global_cleanup();
return 0;
}
// gcc -Wall -Wextra telegramgetup.c -o telegramgetup -lcurl
// ./telegramgetup
Makefile для роутера
include $(TOPDIR)/rules.mk
PKG_NAME:=telegramgetup
PKG_VERSION:=1
PKG_RELEASE:=1
PKG_BUILD_DIR:= $(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
define Package/telegramgetup
SECTION:=utils
CATEGORY:=Utilities
TITLE:=telegramgetup - Telegramgetup utility
DEPENDS:=+libcurl
endef
define Package/telegramgetup/description
telegramgetup - Telegramgetup utility
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Build/Compile
$(TARGET_CC) $(TARGET_CFLAGS) -c -o $(PKG_BUILD_DIR)/telegramgetup.o $(PKG_BUILD_DIR)/telegramgetup.c
$(TARGET_CC) $(TARGET_LDFLAGS) -o $(PKG_BUILD_DIR)/telegramgetup $(PKG_BUILD_DIR)/telegramgetup.o -lcurl
endef
define Package/telegramgetup/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/telegramgetup $(1)/usr/sbin/
endef
$(eval $(call BuildPackage,telegramgetup))
// make package/telegramgetup/compile V=s
Отправьте боту букву w, он ответит — Reciv 'w' OK!
Собственно описывать тут особо нечего, так что на этом всё. Спасибо.
Читать про libcurl тут и тут.
Эта статья опубликована мной на geektimes.
- +5
- stD
8324
Поддержать автора
Комментарии (0)