Telegrambot на СИ — часть вторая

Telegrambot на СИ — часть втораяЗдравствуйте. Это небольшое продолжение, коротенькой статьи про написание телеграмбота.

В предыдущем примере для получения и отправки сообщений использовалась библиотека libcurl. Здесь же она применяется только для получения, а отправка происходит посредством обычного curl‘а.

В примере показано как устанавливать/удалять кнопки (обычные и инлаин) и отправлять картинки (видео, аудио, документы и голосовые сообщения отправляются так же как и картинки).

В исходнике даны необходимые комментарии.

Код

#include  #include  #include  #include   #define BOT_ADDRESS "https://api.telegram.org/bot396653803:AwwhzdUskmV1thviIWOo66cpQ5-3o" // тута ваш токен #define GET_METHOD_READ_SIZE 128 #define TELWRITESIZE 512 // следите за этим размером  typedef struct {     size_t size;     char *text; } json_message;  char tel_write[TELWRITESIZE] = {0,};  //////////////////////////////// reciv from telegram ///////////////////////////////////////// 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] = '';     return real_size; }  ////////////////////////////////////////////// clear_string /////////////////////////////////////////////////////// static void clear_string(char *src) // убирает некоторые символы из полученной json-строки {   char *dst;   if(!src) return;   for(dst = src; *src; src++)    {      if(*src == '"' || *src == '{' || *src == '}' || *src == '[' || *src == ']' || *src == 'n') continue;       *dst++ = *src;    }    *dst = 0; }  /////////////////////////////////////////////////////////////////////////////////// int main() {     char tel_write[TELWRITESIZE] = {0,};     snprintf(tel_write, TELWRITESIZE - 1, "curl -F 'text=START TELEgetUP' '%s/sendMessage?chat_id=376716150' 2> /dev/null 1> /dev/null", BOT_ADDRESS);     system(tel_write);          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,};     int ercount = 0;     int er_tel = 0;      while(1)      {        in_message.text = malloc(1);        if(in_message.text == NULL) // если не удалось выделить память за 10 попыток, тогда exit         {           ercount++;           printf("Error! memory not allocated.n");           if(ercount > 10) exit(0);           sleep(1);           continue;         }        in_message.text[0] = '';          snprintf(GET_read, GET_METHOD_READ_SIZE - 1, "%s/getUpdates?limit=1&offset=%lu&timeout=30", BOT_ADDRESS, update_id); // обновления каждые 30 сек (timeout=30)        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:%dn", result);        else printf("cURL_1_OKn");                clear_string(in_message.text); // эта функция очистит принятую json-строку от символов { } [ ] n "               update_id = 0;              /////////////////////////// chek error ///////////////////////////////        if(strstr(in_message.text, "ok:false") != NULL) // проверка ошибок, например неверный токен         {           er_tel++;           printf("ERROR: %s_ENDnn", in_message.text + 9);           if(er_tel > 10) exit(0);         }                   else er_tel = 0;           /////////////////////////// read update_id ///////////////////////////////        char *p = NULL;        if((p = strstr(in_message.text, "update_id:")) != NULL)          {           update_id = strtoul(p + 10, NULL, 0);           printf("nMYupdate_1_id:%lu_ENDnn", 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 + 8, ',', 15);            chat_id[strlen(chat_id) - 1] = 0;         }                       //////////////////////////// read msag  ////////////////////////////////        char msg_text[16] = {0,};        if((p = strstr(in_message.text, "text:")) != NULL)          {           memcpy(msg_text, p + 5, 15);            msg_text[strlen(msg_text)] = 0;         }                       in_message.size = 0;        free(in_message.text);         ///////////////////////////// my functions  ////////////////////////////////        if(strstr(msg_text, "2 but") != NULL) // установит 2 кнопки в один ряд         { 	  snprintf(tel_write, TELWRITESIZE - 1, "curl  '%s/sendMessage?chat_id=%s' -F 'text=set 2 buttons' -F 'reply_markup={"keyboard":[[{"text":"button 1"},{"text":"button 2"}]],"resize_keyboard":true}' 2> /dev/null 1> /dev/null", BOT_ADDRESS, chat_id); 	  system(tel_write);           }                 if(strstr(msg_text, "5 but") != NULL) // установит 5 кнопок в два ряда         { 	  snprintf(tel_write, TELWRITESIZE - 1, "curl  '%s/sendMessage?chat_id=%s' -F 'text=set 5 buttons' -F 'reply_markup={"keyboard":[[{"text":"button 1"},{"text":"button 2"}],[{"text":"button 3"},{"text":"button 4"},{"text":"button 5"}]],"resize_keyboard":true}' 2> /dev/null 1> /dev/null", BOT_ADDRESS, chat_id); 	  system(tel_write);          }                   if(strstr(msg_text, "button 1") != NULL) // реакция на нажите button 1         { 	  snprintf(tel_write, TELWRITESIZE - 1, "curl -F 'text=click button 1' '%s/sendMessage?chat_id=%s' 2> /dev/null 1> /dev/null", BOT_ADDRESS, chat_id);           system(tel_write);         }                  if(strstr(msg_text, "del but") != NULL) // удалит кнопки         { 	  snprintf(tel_write, TELWRITESIZE - 1, "curl  '%s/sendMessage?chat_id=%s' -F 'text=del buttons' -F 'reply_markup={"remove_keyboard":true}' 2> /dev/null 1> /dev/null", BOT_ADDRESS, chat_id); 	  system(tel_write);         }                  if(strstr(msg_text, "2 inlbut") != NULL) // установит 2 инлаин-кнопки в один ряд         { 	  snprintf(tel_write, TELWRITESIZE - 1, "curl  '%s/sendMessage?chat_id=%s' -F 'text=set 2 inline-buttons' -F 'reply_markup={"inline_keyboard":[[{"text":"Geektimes","url":"https://geektimes.ru"},{"text":"Geektimes","url":"https://geektimes.ru"}]]}' 2> /dev/null 1> /dev/null", BOT_ADDRESS, chat_id); 	  system(tel_write);         }                   if(strstr(msg_text, "5 inlbut") != NULL) // установит 5 инлаин-кнопок в два ряда         { 	  snprintf(tel_write, TELWRITESIZE - 1, "curl  '%s/sendMessage?chat_id=%s' -F 'text=set 5 inline-buttons' -F 'reply_markup={"inline_keyboard":[[{"text":"Geektimes","url":"https://geektimes.ru"},{"text":"Geektimes","url":"https://geektimes.ru"}],[{"text":"Geektimes","url":"https://geektimes.ru"},{"text":"Geektimes","url":"https://geektimes.ru"},{"text":"Geektimes","url":"https://geektimes.ru"}]]}' 2> /dev/null 1> /dev/null", BOT_ADDRESS, chat_id); 	  system(tel_write);         }                  if(strstr(msg_text, "picurl") != NULL) // отправит картинку url         {           snprintf(tel_write, TELWRITESIZE - 1, "curl -F 'photo=https://hsto.org/getpro/geektimes/post_images/25f/64d/8ef/25f64d8ef8c20008190eb6747a303061.png' -F 'caption=Picture url' '%s/sendPhoto?chat_id=%s' 2> /dev/null 1> /dev/null", BOT_ADDRESS, chat_id);           system(tel_write);         }                   if(strstr(msg_text, "locpic") != NULL)  // отправит локальную картинку         {           snprintf(tel_write, TELWRITESIZE - 1, "curl -F 'photo=@tux.png' -F 'caption=local picture' -H 'Content-Type:multipart/form-data' '%s/sendPhoto?chat_id=%s' 2> /dev/null 1> /dev/null", BOT_ADDRESS, chat_id); // либо добавте путь к картинке photo=@/tmp/tux.png           system(tel_write);         }                         else if(strstr(msg_text, "/start") != NULL)          {           snprintf(tel_write, TELWRITESIZE - 1, "curl -F 'text=Hello' '%s/sendMessage?chat_id=%s' 2> /dev/null 1> /dev/null", BOT_ADDRESS, chat_id);           system(tel_write);         }          else printf("NO_DATAn");        printf("Tel_write=%dn", (int)strlen(tel_write));     }        curl_global_cleanup();    return 0; }   // gcc -Wall -Wextra telegramgetup.c -o telegramgetup -lcurl  // ./telegramgetup 

О том, как компилить для роутера, написано в прошлый раз.

Почему для отправки используется curl? Отчасти из-за того, что — «почему бы нет», а отчасти из-за того, что мне так и не удалось заставить libcurl отправить в заголовке «Content-Type: multipart/form-data» по https. )))

Спасибо.

П.С. токен показан не валидный.

 
Источник

Читайте также