Etiquetas

C (31) Cpp (28) Linux (14) asm (8) Telegram (5) bot (5) libreria (5) Algoritmo (3) Errores comunes (3) python (3) Opengl (2) kali (2) Android (1) Snippet (1) nano (1) recursividad (1)
Mostrando las entradas con la etiqueta Telegram. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Telegram. Mostrar todas las entradas

viernes, 24 de noviembre de 2023

bot telegram (5) telegram.h

 /*
 * Luis Alberto
 * Twitter @albertobsd
 */


#ifndef __TBOT_H_
#define __TBOT_H_
#include"jsmn.h"

enum chat_type{
chat_private = 0,
chat_group = 1,
chat_supergroup = 2,
chat_channel = 3};

typedef struct{
char *phone_number;
char *first_name;
char *last_name;
int user_id;
}Contact;

typedef struct{
char *file_id;
int duration;
char *mime_type;
int file_size;
}Voice;

typedef struct{
char *file_id;
int width;
int height;
int file_size;
} PhotoSize;

typedef struct{
int length;
PhotoSize **item;
}Photos;

typedef struct{
char *file_id;
PhotoSize *thumb;
char *file_name;
char *mime_type;
int file_size;
}Document;

typedef struct{
char *file_id;
int width;
int height;
PhotoSize *thumb;
int file_size;
}Sticker;

typedef struct{
int id;
enum chat_type type;
char *title;
char *username;
char *first_name;
char *last_name;
}Chat;

typedef struct{
int id;
char *first_name;
char *last_name;
char *username;
}User;

typedef struct{
float longitude;
float latitude;
}Location;

typedef struct{
char *file_id;
int width;
int height;
int duration;
PhotoSize *thumb;
char *mime_type;
int file_size;
}Video;

typedef struct Message {
        int message_id;
        User *from;
        int date;
        Chat *chat;
        User *forward_from;
        int forward_date;
        struct Message *reply_to_message;
        char *text;
        void *audio;
        Document *document;
        Photos *photo;
        Sticker *sticker;
        Video *video;
        Voice *voice;
        char *caption;
        Contact *contact;
        Location *location;
        User *new_chat_participant;
        User *left_chat_participant;
        char *new_chat_title;
        Photos *new_chat_photo;
        int delete_chat_photo;
        int group_chat_created;
        int supergroup_chat_created;
        int channel_chat_created;
        int migrate_to_chat_id;
        int migrate_from_chat_id;
}Message;

typedef struct  {
        char *ok;
        char *result;
        int error_code;
        char *description;
}Response;

typedef struct {
        int update_id;
        int type;
        union  {
                Message *message;
        }item;
}Update;

typedef struct  {
        int length;
        Update **list;
}Updates;

typedef struct  {
        char *file_id;
        int file_size;
        char *file_path;
}File;

typedef struct {
        char *file_id;
        int duration;
        char *performer;
        char *title;
        char *mime_type;
        int file_size;
}Audio;

typedef enum {
        TELEGRAM_ERROR_CURL_= 1,
        TELEGRAM_ERROR_API_RESPONSE = -10,
        TELEGRAM_ERROR_DEVELOPER = -20,
        TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE  = -30,
        TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE = -40,
        TELEGRAM_ERROR_API_404 = 404
}telegram_error_t;




/*
 * free telegram variables funtions
 */

Response* telegram_free_response(Response *res);
User* telegram_free_user(User *user);
Update* telegram_free_update(Update *update);
Updates* telegram_free_updates(Updates *updates);
Message* telegram_free_message(Message *message);
Document* telegram_free_document(Document *document);
Video* telegram_free_video(Video *video);
Voice* telegram_free_voice(Voice *voice);
Audio* telegram_free_audio(Audio *audio);
Sticker* telegram_free_sticker(Sticker *sticker);
Chat* telegram_free_chat(Chat *chat);
Photos* telegram_free_photos(Photos *photos);
Contact* telegram_free_contact(Contact *contact);
Location* telegram_free_location(Location *location);
PhotoSize* telegram_free_photosize(PhotoSize *photosize);



int telegram_init(char *);
int indexOf(char *str,char **ptr_strings);
int telegram_jsmn_init(jsmn_parser *parser,jsmntok_t **t,char *buffer,int *n);
int telegram_set_error(char *error_str,int error_code);
char * telegram_jsmn_get_token(jsmntok_t token,char *full);
void telegram_dump_token(jsmntok_t token,char *str);
char *telegram_makeurl(char *telegram_method);
char *telegram_get_error();
int telegram_is_error();
char* telegram_build_post(char **variables,char **values);


int telegram_reset_buffer();
size_t write_callback(void *ptr, size_t size, size_t nmemb, void *userdata );
off_t fsize(const char *filename);

/*
 * Telegram API methods
 */

User * telegram_getMe();
Updates * telegram_getUpdates();
Message* telegram_sendMessage(char *postdata);
File* telegram_getFile(char *file_id);
Message* telegram_sendDocument(char *filename,char **variables, char **valores);


/*
 * Telegram parse
 */

User * telegram_parse_user(char *str,int *count);
Response* telegram_parse_response(char *str,int *count);
Updates* telegram_parse_updates(char *str,int *count);
Update* telegram_parse_update(char *str,int *count);
Message* telegram_parse_message(char *str,int *count);
Chat* telegram_parse_chat(char *str,int *count);
PhotoSize* telegram_parse_photosize(char *str,int *count);
Photos* telegram_parse_photos(char *str,int *count);
Sticker* telegram_parse_sticker(char *str,int *count);
Voice* telegram_parse_voice(char *str,int *count);
Location* telegram_parse_location(char *str,int *count);
Contact* telegram_parse_contact(char *str,int *count);
Document* telegram_parse_document(char *str,int *count);
Video* telegram_parse_video(char *str,int *count);
File* telegram_parse_file(char *str,int *count);
char* telegram_downloadFile(File *file,char *name);
char* telegram_process_slash(char *str);
CURL* telegram_curl_init();


#endif /* __TBOT_H_ */

bot telegram (4) jsmn.h

 #ifndef __JSMN_H_
#define __JSMN_H_

#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * JSON type identifier. Basic types are:
 *      o Object
 *      o Array
 *      o String
 *      o Other primitive: number, boolean (true/false) or null
 */
typedef enum {
        JSMN_UNDEFINED = 0,
        JSMN_OBJECT = 1,
        JSMN_ARRAY = 2,
        JSMN_STRING = 3,
        JSMN_PRIMITIVE = 4
} jsmntype_t;

enum jsmnerr {
        /* Not enough tokens were provided */
        JSMN_ERROR_NOMEM = -1,
        /* Invalid character inside JSON string */
        JSMN_ERROR_INVAL = -2,
        /* The string is not a full JSON packet, more bytes expected */
        JSMN_ERROR_PART = -3
};

/**
 * JSON token description.
 * @param               type    type (object, array, string etc.)
 * @param               start   start position in JSON data string
 * @param               end             end position in JSON data string
 */
typedef struct {
        jsmntype_t type;
        int start;
        int end;
        int size;
#ifdef JSMN_PARENT_LINKS
        int parent;
#endif
} jsmntok_t;

/**
 * JSON parser. Contains an array of token blocks available. Also stores
 * the string being parsed now and current position in that string
 */
typedef struct {
        unsigned int pos; /* offset in the JSON string */
        unsigned int toknext; /* next token to allocate */
        int toksuper; /* superior token node, e.g parent object or array */
} jsmn_parser;

/**
 * Create JSON parser over an array of tokens
 */
void jsmn_init(jsmn_parser *parser);

/**
 * Run JSON parser. It parses a JSON data string into and array of tokens, each describing
 * a single JSON object.
 */
int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
                jsmntok_t *tokens, unsigned int num_tokens);

#ifdef __cplusplus
}
#endif

#endif /* __JSMN_H_ */

Bot telegram (3) test_telegram.c

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<curl/curl.h>
#include<sys/stat.h>
#include<errno.h>
#include"telegram.h"
#include"jsmn.h"

int main()      {
        Updates *updates;
        User *user;
        File *file;
        int i = 0;
        char *filename;
        telegram_init("1234567:fghjkl45678xcvbkcvbnzsxdcfvgbh");
        user = telegram_getMe();
        if(!telegram_is_error())        {
                printf("User: id: %i\nusername: %s\n",user->id,user->username);
                telegram_free_user(user);
        }
        else    {
                printf("%s\n",telegram_get_error());
        }
        updates = telegram_getUpdates();
        if(!telegram_is_error()){
                printf("updates: %i\n",updates->length);
                while(i < updates->length)      {
                        if(updates->list[i]->item.message->document)    {
                                printf("Document exits file_id : %s\n",updates->list[i]->item.message->document->file_id);
                                file = telegram_getFile(updates->list[i]->item.message->document->file_id);
                                if(!telegram_is_error())        {
                                        filename = telegram_downloadFile(file,updates->list[i]->item.message->document->file_name);
                                        printf("file name : %s\n",filename);
                                }
                                else    {
                                        printf("%s\n",telegram_get_error());
                                }
                        }
                        i++;
                }
                telegram_free_updates(updates);
        }
        else    {
                printf("%s\n",telegram_get_error());
        }
        return 0;
}

Bot telegram (2) jsmn.c

 #include "jsmn.h"
/* Allocates a fresh unused token from the token pull.*/
static jsmntok_t *jsmn_alloc_token
(jsmn_parser *parser,jsmntok_t *tokens, size_t num_tokens){
jsmntok_t *tok;
if (parser->toknext >= num_tokens){return NULL;}
tok = &tokens[parser->toknext++];
tok->start = tok->end = -1;tok->size = 0;

#ifdef JSMN_PARENT_LINKS
tok->parent = -1;
#endif
return tok;}

/* Fills token type and boundaries.*/
static void jsmn_fill_token
(jsmntok_t *token, jsmntype_t type,int start, int end){
token->type = type;token->start = start;
token->end = end;token->size = 0;}

/*Fills next available token with JSON primitive.*/
static int jsmn_parse_primitive
(jsmn_parser *parser, const char *js,size_t len, jsmntok_t *tokens, size_t num_tokens) {
jsmntok_t *token;int start;start = parser->pos;

for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
switch (js[parser->pos]) {
#ifndef JSMN_STRICT
/* In strict mode primitive must be followed by "," or "}" or "]" */
case ':':
#endif
case '\t' : case '\r' : case '\n' : case ' ' :
case ','  : case ']'  : case '}' :
goto found;
}

if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
parser->pos = start;return JSMN_ERROR_INVAL;}
        }
#ifdef JSMN_STRICT
/* In strict mode primitive must be followed by a comma/object/array */
parser->pos = start;
return JSMN_ERROR_PART;
#endif

found:
if (tokens == NULL){parser->pos--;return 0;}
token = jsmn_alloc_token(parser, tokens, num_tokens);
if (token == NULL) {parser->pos = start;return JSMN_ERROR_NOMEM;}
jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
#ifdef JSMN_PARENT_LINKS
token->parent = parser->toksuper;
#endif
parser->pos--;
return 0;}

/*Fills next token with JSON string.*/
static int jsmn_parse_string
(jsmn_parser *parser, const char *js,size_t len, jsmntok_t *tokens, size_t num_tokens) {
jsmntok_t *token;int start = parser->pos;
parser->pos++;

/* Skip starting quote */
for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
char c = js[parser->pos];

/* Quote: end of string */
if (c == '\"') {
if (tokens == NULL) {return 0;}
token = jsmn_alloc_token(parser, tokens, num_tokens);
if (token == NULL) {parser->pos = start;return JSMN_ERROR_NOMEM;}
jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
#ifdef JSMN_PARENT_LINKS
token->parent = parser->toksuper;
#endif
return 0;}

/* Backslash: Quoted symbol expected */
if (c == '\\' && parser->pos + 1 < len) {
int i;parser->pos++;

switch (js[parser->pos]) {
/* Allowed escaped symbols */
case '\"': case '/' : case '\\' : case 'b' :
case 'f' : case 'r' : case 'n'  : case 't' :break;
/* Allows escaped symbol \uXXXX */

case 'u':
parser->pos++;
for(i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) {
/* If it isn't a hex character we have an error */
if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */
(js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
(js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */
parser->pos = start;
return JSMN_ERROR_INVAL;}

parser->pos++;}
parser->pos--; break;

/* Unexpected symbol */
default:
parser->pos = start;
return JSMN_ERROR_INVAL;}
                }
        }

parser->pos = start;
return JSMN_ERROR_PART;
}

/*Parse JSON string and fill tokens.*/
int jsmn_parse
(jsmn_parser *parser,
const char *js,
size_t len,
jsmntok_t *tokens,

unsigned int num_tokens) {
int r;int i;
jsmntok_t *token;
int count = parser->toknext;

for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
char c;jsmntype_t type;
c = js[parser->pos];

switch (c) {
case '{': case '[':
count++;
if (tokens == NULL) {break;}
token = jsmn_alloc_token(parser, tokens, num_tokens);
if (token == NULL) return JSMN_ERROR_NOMEM;
if (parser->toksuper != -1) {
tokens[parser->toksuper].size++;
#ifdef JSMN_PARENT_LINKS
token->parent = parser->toksuper;
#endif
}
token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
token->start = parser->pos;parser->toksuper = parser->toknext - 1;
break;

case '}': case ']':
if (tokens == NULL) break;
type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
#ifdef JSMN_PARENT_LINKS
if (parser->toknext < 1) {return JSMN_ERROR_INVAL;}
token = &tokens[parser->toknext - 1];

for (;;) {
if (token->start != -1 && token->end == -1) {
if (token->type != type) {return JSMN_ERROR_INVAL;}
token->end = parser->pos + 1;parser->toksuper = token->parent;
break;}

if (token->parent == -1) {break;}
token = &tokens[token->parent];
                                }
#else
for (i = parser->toknext - 1; i >= 0; i--) {
token = &tokens[i];

if (token->start != -1 && token->end == -1) {
if (token->type != type) {return JSMN_ERROR_INVAL;}
parser->toksuper = -1;token->end = parser->pos + 1;
break;}

}
                                /* Error if unmatched closing bracket */
if (i == -1) return JSMN_ERROR_INVAL;
for (; i >= 0; i--) {
token = &tokens[i];
if (token->start != -1 && token->end == -1)
{parser->toksuper = i;break;}
}
#endif
break;

case '\"':
r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
if (r < 0) return r;count++;

if (parser->toksuper != -1 && tokens != NULL)
tokens[parser->toksuper].size++;break;

case '\t' : case '\r' : case '\n' : case ' ':break;
case ':':parser->toksuper = parser->toknext - 1;break;
case ',':
if (tokens != NULL && parser->toksuper != -1 &&
tokens[parser->toksuper].type != JSMN_ARRAY &&
tokens[parser->toksuper].type != JSMN_OBJECT) {
#ifdef JSMN_PARENT_LINKS
parser->toksuper = tokens[parser->toksuper].parent;
#else
for (i = parser->toknext - 1; i >= 0; i--) {
if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) {

if (tokens[i].start != -1 && tokens[i].end == -1)
{parser->toksuper = i;break;}

}}
#endif
                                }
                                break;
#ifdef JSMN_STRICT
                        /* In strict mode primitives are: numbers and booleans */
                        case '-': case '0': case '1' : case '2': case '3' : case '4':
                        case '5': case '6': case '7' : case '8': case '9':
                        case 't': case 'f': case 'n' :
                                /* And they must not be keys of the object */
                                if (tokens != NULL && parser->toksuper != -1) {
                                        jsmntok_t *t = &tokens[parser->toksuper];
                                        if (t->type == JSMN_OBJECT ||
                                                        (t->type == JSMN_STRING && t->size != 0)) {
                                                return JSMN_ERROR_INVAL;
                                        }
                                }
#else
                        /* In non-strict mode every unquoted value is a primitive */
                        default:
#endif
                                r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
                                if (r < 0) return r;
                                count++;
                                if (parser->toksuper != -1 && tokens != NULL)
                                        tokens[parser->toksuper].size++;
                                break;

#ifdef JSMN_STRICT
                        /* Unexpected char in strict mode */
                        default:
                                return JSMN_ERROR_INVAL;
#endif
                }
        }

        if (tokens != NULL) {
                for (i = parser->toknext - 1; i >= 0; i--) {
                        /* Unmatched opened object or array */
                        if (tokens[i].start != -1 && tokens[i].end == -1) {
                                return JSMN_ERROR_PART;
                        }
                }
        }

        return count;
}

/**
 * Creates a new parser based over a given  buffer with an array of tokens
 * available.
 */
void jsmn_init(jsmn_parser *parser) {
        parser->pos = 0;
        parser->toknext = 0;
        parser->toksuper = -1;
}

Bot telegram (1)main.c

 /*
 * Luis Alberto
 * Twitter @albertobsd
 */

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<curl/curl.h>
#include<sys/stat.h>
#include<errno.h>
#include"telegram.h"
#include"jsmn.h"

char *telegram_buffer;
int telegram_buffer_size = 1024;
int telegram_buffer_offset = 0;
char *telegram_baseurl = "https://api.telegram.org/bot";
char *telegram_fileurl = "https://api.telegram.org/file/bot";
char *telegram_token;
int telegram_error = 0;
int telegram_error_code = 0;
char *telegram_error_buffer;

char *message_names[] = {"message_id","from","date","chat",
"forward_from","forward_date","reply_to_message",
"text","audio","document","photo","sticker","video",
"voice","caption","contact","location",
"new_chat_participant","left_chat_participant",
"new_chat_title","new_chat_photo","delete_chat_photo",
"group_chat_created","supergroup_chat_created",
"channel_chat_created","migrate_to_chat_id","migrate_from_chat_id",NULL};

char *contact_names[] = {"phone_number","first_name","last_name","user_id",NULL};
char *chat_names[] = {"id","type","title","username","first_name","last_name",NULL};
char *chat_type_names[] = {"private","group","supergroup","channel",NULL};
char *sticker_names[] = {"file_id","width","height","thumb","file_size",NULL};
char *photosize_names[] = {"file_id","width","height","file_size",NULL};
char *voice_names[] = {"file_id","duration","mime_type","file_size",NULL};
char *location_names[] = {"longitude","latitude",NULL};
char *document_names[] = {"file_id","thumb","file_name","mime_type","file_size",NULL};
char *video_names[] = {"file_id","width","height","duration","thumb","mime_type","file_size",NULL};
char *response_names[] = {"ok","description","result","error_code",NULL};
char *user_names[] = {"id","first_name","last_name","username",NULL};
char *update_names[] = {"update_id","message","inline_query","chosen_inline_result",NULL};
char *file_names[] = {"file_id","file_size","file_path",NULL};

int message_states[3][5] = {{4,1,4,4,4},{4,4,4,2,4},{4,1,1,1,1}};
int parse_array_states[2][5] = {{4,4,1,4,4},{4,1,4,4,4}};

Response *telegram_parse_response(char *str,int *count) {
Response *response;
int r,n =1,c,i =0;
unsigned int state = 0,entrar = 1;
char *variable,*value;
response = calloc(2,sizeof(Response));
jsmntok_t *toks;
jsmn_parser parser;
toks = calloc(n+2,sizeof(jsmntok_t));
r = telegram_jsmn_init(&parser,&toks,str,&n);
while(entrar && i < r)  {
switch(state)   {
case 0:
state = message_states[state][toks[i].type];i++;break;

case 1:
variable = telegram_jsmn_get_token(toks[i],str);
state = message_states[state][toks[i].type];i++;break;

case 2:
value = telegram_jsmn_get_token(toks[i],str);
state = message_states[state][toks[i].type];i++;

switch(indexOf(variable,response_names)){
case 0:response->ok = value;break;
case 1:response->description = value;
telegram_error_buffer = calloc(strlen(value)+2,sizeof(char));
memcpy(telegram_error_buffer,value,strlen(value)*sizeof(char));
entrar = 0;break;
case 2:response->result = value;
entrar = 0;break;
case 3:
response->error_code = strtol(value,NULL,10);
telegram_error = 1;telegram_error_code =  response->error_code;
free(value);break;
default:
telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
entrar = 0;break;}

free(variable);break;
case 3:
telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
entrar = 0;break;

default:
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return response;
}


int telegram_jsmn_init
(jsmn_parser *parser,jsmntok_t **t,char *buffer,int *n){
int r;
jsmntok_t *toks;
jsmn_init(parser);
toks = calloc(n[0]+2,sizeof(jsmntok_t));

if(toks != NULL){
r = jsmn_parse(parser, buffer, strlen(buffer), toks, n[0]);

while (r == JSMN_ERROR_NOMEM){
n[0]*=2;toks = realloc(toks, sizeof(jsmntok_t) * (n[0] + 2));
r = jsmn_parse(parser, buffer, strlen(buffer), toks, n[0]);}

if (r == JSMN_ERROR_INVAL){telegram_set_error("jsmn_parse: invalid JSON string",JSMN_ERROR_INVAL);}
if (r == JSMN_ERROR_PART){telegram_set_error("jsmn_parse: truncated JSON string",JSMN_ERROR_PART);}
t[0] = toks;}else{telegram_set_error("calloc: error",0xDEAD);}
return r;}

int telegram_set_error(char *error_str,int error_code)  {
        telegram_error_buffer = error_str;
        telegram_error_code = error_code;
        telegram_error = 1;
        return 0;
}

Response* telegram_free_response(Response *res) {
        if(res) {
                if(res->ok)     {free(res->ok);}
                if(res->result) {free(res->result);}
                if(res->description){free(res->description);}
                memset(res,0,sizeof(Response));
                free(res);
        }
        return NULL;
}

User* telegram_free_user(User *user){
        if(user){
                if(user->username != NULL){free(user->username);}
                if(user->first_name != NULL){free(user->first_name);}
                if(user->last_name != NULL){free(user->last_name);}
                memset(user,0,sizeof(User));
                free(user);
        }
return NULL;}

int indexOf(char *str,char **ptr_strings){
int i = 0,entrar = 1;

while(entrar && ptr_strings[i] != NULL){
if(strcmp(ptr_strings[i],str) == 0){entrar = 0;i--;}
i++;
}
if(entrar){i = -1;}
return i;}

char * telegram_jsmn_get_token(jsmntok_t token,char *full){
char *str;int size = token.end - token.start;
str = calloc(size+2,sizeof(char));
memcpy(str,full+token.start,size);
return str;}

void telegram_dump_token(jsmntok_t token,char *str){
        char *temp;
        temp = telegram_jsmn_get_token(token,str);
        printf("Token: %s\n",temp);
        free(temp);
        printf("type: %i\n",token.type);
        printf("start: %i\n",token.start);
        printf("end: %i\n",token.end);
        printf("size: %i\n",token.size);
#ifdef JSMN_PARENT_LINKS
        printf("size: %i\n",token.parent);
#endif
}

User* telegram_getMe()  {
        CURL *curl;
        CURLcode res;
        Response *response = NULL;
        User *user = NULL;
        char *url = NULL;
        int i;
        url = telegram_makeurl("/getMe");
        curl = telegram_curl_init();
        curl_easy_setopt(curl, CURLOPT_URL, url);
        res = curl_easy_perform(curl);
        free(url);
        if(res == CURLE_OK)     {
                response = telegram_parse_response(telegram_buffer,&i);
                if(!telegram_error)     {
                        user = telegram_parse_user(response->result,&i);
                }
                telegram_free_response(response);
                telegram_reset_buffer();
                curl_easy_cleanup(curl);
        }
        else    {
                telegram_set_error("curl: curl_easy_perform()",-1000);
        }
        return user;
}

File* telegram_getFile(char *file_id)   {
        CURL *curl;
        CURLcode res;
        Response *response = NULL;
        File *file = NULL;
        char *url = NULL;
        char *postdata = NULL;
        char *variables[] = {"file_id",NULL};
        char *values[] = {file_id,NULL};
        int i;
        if(file_id){
                curl = telegram_curl_init();
                url = telegram_makeurl("/getFile");
                curl_easy_setopt(curl, CURLOPT_URL, url);
                postdata = telegram_build_post(variables,values);
                curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata);
                res = curl_easy_perform(curl);
                free(url);
                if(res == CURLE_OK)     {
                        response = telegram_parse_response(telegram_buffer,&i);
                        if(!telegram_error)     {
                                file = telegram_parse_file(response->result,&i);
                        }
                        telegram_free_response(response);
                        telegram_reset_buffer();
                }
                else    {
                        telegram_set_error("curl_easy_perform() failed!",-1000);
                }
                free(postdata);
                curl_easy_cleanup(curl);
        }
        else    {
                telegram_set_error("NULL file_id",-10);
        }
        return file;
}

char *telegram_makeurl(char *telegram_method)   {
        char *url;
        int l;
        int size_base;
        int size_token;
        int size_method;
        size_base = strlen(telegram_baseurl);
        size_token = strlen(telegram_token);
        size_method = strlen(telegram_method);
        l = size_base + size_token + size_method;
        url = calloc(l+2,sizeof(char));
        if(url != NULL) {
                snprintf(url,l+1,"%s%s%s",telegram_baseurl,telegram_token,telegram_method);
        }
        else    {
                fprintf(stderr,"calloc error\n");
                exit(1);
        }
        return url;
}

User* telegram_parse_user(char *str,int *count) {
        User *user;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        char *token,*token1;
        jsmntok_t *toks;
        jsmn_parser parser;
        user = calloc(2,sizeof(User));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                                switch(indexOf(variable,user_names))    {
                                        case 0:
                                                user->id = strtol(value,NULL,10);
                                                free(value);
                                        break;
                                        case 1:
                                                user->first_name = value;
                                        break;
                                        case 2:
                                                user->last_name = value;
                                        break;
                                        case 3:
                                                user->username = value;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 3:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0] += r;
        return user;
}

int telegram_reset_buffer()     {
        memset(telegram_buffer,0,telegram_buffer_size);
        telegram_buffer_offset = 0;
        return 0;
};

size_t write_callback(void *ptr, size_t size, size_t nmemb, void *userdata )    {
        size_t new_len = telegram_buffer_offset + size*nmemb;
        if(new_len >= telegram_buffer_size)     {
                do      {
                        telegram_buffer_size*=2;
                }while(new_len >= telegram_buffer_size);
                telegram_buffer = realloc(telegram_buffer, (telegram_buffer_size +2)*sizeof(char));
                if (telegram_buffer == NULL) {
                        fprintf(stderr, "realloc() failed\n");
                        exit(EXIT_FAILURE);
                }
        }
        memcpy(telegram_buffer + telegram_buffer_offset, ptr, size*nmemb);
        telegram_buffer[new_len] = '\0';
        telegram_buffer_offset+= size*nmemb;
        return size*nmemb;
}

off_t fsize(const char *filename) {
        struct stat st;
        if (stat(filename, &st) == 0)
                return st.st_size;
        fprintf(stderr, "Cannot determine size of %s: %s\n",filename, strerror(errno));
        return -1;
}

Updates * telegram_getUpdates() {
        CURL *curl;
        CURLcode res;
        Response *response = NULL;
        Updates *updates = NULL;
        char *url = telegram_makeurl("/getUpdates");
        int i;
        curl = telegram_curl_init();
        curl_easy_setopt(curl, CURLOPT_URL, url);
        res = curl_easy_perform(curl);
        free(url);
        if(res == CURLE_OK)     {
                response = telegram_parse_response(telegram_buffer,&i);
                if(!telegram_error)     {
                        if(response && response->result){
                                updates = telegram_parse_updates(response->result,&i);
                        }
                }
                telegram_free_response(response);
                telegram_reset_buffer();
                curl_easy_cleanup(curl);
        }
        else    {
                telegram_set_error("curl: curl_easy_perform()",-1000);
        }
        return updates;
}

Updates * telegram_parse_updates(char *str,int *count)  {
        Updates *updates;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *value;
        updates = calloc(2,sizeof(Updates));
        updates->list = calloc(2,sizeof(Update*));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+2,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = parse_array_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = parse_array_states[state][toks[i].type];
                                updates->list[updates->length] = telegram_parse_update(value,&i);
                                updates->length++;
                                updates->list = realloc(updates->list,(updates->length+2)*sizeof(Update *));
                        break;
                        case 4:
                                telegram_dump_token(toks[i],str);
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return updates;
}

Update * telegram_parse_update(char *str,int *count)    {
        Update *update = NULL;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        update = calloc(2,sizeof(Update));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                switch(indexOf(variable,update_names))  {
                                        case 0:
                                                update->update_id = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 1:
                                                update->item.message = telegram_parse_message(value,&i);
                                                free(value);
                                        break;
                                        case 2:
                                        case 3:
                                                telegram_set_error("Fixme",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                free(value);
                                                entrar = 0;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 3:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                        default:
                        break;
                }

        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+= r;
        return update;
}

Message* telegram_parse_message(char *str,int *count)   {
        Message *message;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        message = calloc(2,sizeof(Message));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,message_names);
                                switch(c)       {
                                        case 0: //message_id
                                                message->message_id = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 1: //from
                                                message->from = telegram_parse_user(value,&i);
                                                free(value);
                                        break;
                                        case 2: //date
                                                message->date = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 3: //chat
                                                message->chat= telegram_parse_chat(value,&i);
                                                free(value);
                                        break;
                                        case 4: //forward_from
                                                message->forward_from = telegram_parse_user(value,&i);
                                                free(value);
                                        break;
                                        case 5: //forward_date
                                                message->forward_date = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 6: //reply_to_message
                                                message->reply_to_message = telegram_parse_message(value,&i);
                                                free(value);
                                        break;
                                        case 7: //text
                                                message->text = value;
                                                i++;
                                        break;
                                        case 8: //audio
                                                printf("error with token %s\n",value);
                                                entrar = 0;
                                                free(value);
                                                i++;
                                        break;
                                        case 9: //document
                                                message->document = telegram_parse_document(value,&i);
                                                free(value);
                                        break;
                                        case 10: //photo
                                                message->photo = telegram_parse_photos(value,&i);
                                                free(value);
                                        break;
                                        case 11:

                                                message->sticker = telegram_parse_sticker(value,&i);
                                                free(value);
                                        break;
                                        case 12:        //video
                                                message->video = telegram_parse_video(value,&i);
                                        break;
                                        case 13:        //voice
                                                message->voice = telegram_parse_voice(value,&i);
                                                free(value);
                                        break;
                                        case 14:        //Cption
                                                message->caption = value;
                                                i++;
                                        break;
                                        case 15:        //contact
                                                message->contact = telegram_parse_contact(value,&i);
                                                free(value);
                                        break;
                                        case 16:        //location
                                                message->location = telegram_parse_location(value,&i);
                                                free(value);
                                        break;
                                        case 17:        //new_chat_participant
                                                message->new_chat_participant = telegram_parse_user(value,&i);
                                                free(value);
                                        break;
                                        case 18:        //left_chat_participant
                                                message->left_chat_participant = telegram_parse_user(value,&i);
                                                free(value);
                                        break;
                                        case 19:        //new_chat_title
                                                message->new_chat_title = value;
                                                i++;
                                        break;
                                        case 20:        //new_chat_photo
                                                message->new_chat_photo = telegram_parse_photos(value,&i);
                                                free(value);
                                        break;
                                        case 21:        //delete_chat_photo
                                                message->delete_chat_photo = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 22:        //group_chat_created
                                                message->group_chat_created = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 23:        //supergroup_chat_created
                                                message->supergroup_chat_created = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 24:        //channel_chat_created
                                                message->channel_chat_created = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 25:        //migrate_to_chat_id
                                                message->migrate_to_chat_id = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 26:        //migrate_from_chat_id
                                                message->migrate_from_chat_id = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                        default:
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return message;
}

Chat* telegram_parse_chat(char *str,int  *count)        {
        Chat *chat = NULL;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        chat = calloc(2,sizeof(Chat));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                                switch(indexOf(variable,chat_names))    {
                                        case 0:
                                                chat->id = strtol(value,NULL,10);
                                                free(value);
                                        break;
                                        case 1:
                                                chat->type = indexOf(variable,chat_type_names);
                                        break;
                                        case 2:
                                                chat->title = value;
                                        break;
                                        case 3:
                                                chat->username = value;
                                        break;
                                        case 4:
                                                chat->first_name = value;
                                        break;
                                        case 5:
                                                chat->last_name = value;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;

                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return chat;
}

Sticker* telegram_parse_sticker(char *str,int *count)   {
        Sticker *sticker = NULL;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        sticker = calloc(2,sizeof(Sticker));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                switch(indexOf(variable,sticker_names)) {
                                        case 0:
                                                sticker->file_id = value;
                                                i++;
                                        break;
                                        case 1:
                                                sticker->width = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 2:
                                                sticker->height = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 3:
                                                sticker->thumb = telegram_parse_photosize(value,&i);
                                                free(value);
                                        break;
                                        case 4:
                                                sticker->file_size = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;

                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return sticker;
}

PhotoSize* telegram_parse_photosize(char *str,int *count)       {
        PhotoSize *photosize = NULL;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        photosize = calloc(2,sizeof(PhotoSize));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,photosize_names);
                                switch(c)       {
                                        case 0:
                                                photosize->file_id = value;
                                                i++;
                                        break;
                                        case 1:
                                                photosize->width = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 2:
                                                photosize->height = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 3:
                                                photosize->file_size = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return photosize;
}

Photos* telegram_parse_photos(char *str,int *count)     {
        Photos *photos = NULL;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *value;
        photos = calloc(2,sizeof(Photos));
        photos->length = 0;
        photos->item = calloc(2,sizeof(PhotoSize *));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = parse_array_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = parse_array_states[state][toks[i].type];
                                photos->item[photos->length] = telegram_parse_photosize(value,&i);
                                photos->length++;
                                photos->item = realloc(photos->item,(photos->length+2) * sizeof(PhotoSize*));
                        break;
                        case 4:
                                telegram_dump_token(toks[i],str);
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+= r;
        return photos;

}

Voice* telegram_parse_voice(char *str,int *count)       {
        Voice *voice;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        voice = calloc(2,sizeof(Voice));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,voice_names);
                                i++;
                                switch(c)       {
                                        case 0:
                                                voice->file_id = value;
                                        break;
                                        case 1:
                                                voice->duration = strtol(value,NULL,10);
                                                free(value);
                                        break;
                                        case 2:
                                                voice->mime_type = value;
;
                                        case 3:
                                                voice->file_size = strtol(value,NULL,10);
                                                free(value);
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return voice;
}

Location* telegram_parse_location(char *str,int *count) {
        Location *location;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        location = calloc(2,sizeof(Location));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,location_names);
                                i++;
                                switch(c)       {
                                        case 0:
                                                location->longitude = strtof(value,NULL);
                                        break;
                                        case 1:
                                                location->latitude = strtof(value,NULL);
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(value);
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return location;
}

Contact* telegram_parse_contact(char *str,int *count)   {
        Contact *contact;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        contact = calloc(2,sizeof(Contact));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,contact_names);
                                i++;
                                switch(c)       {
                                        case 0:
                                                contact->phone_number = value;
                                        break;
                                        case 1:
                                                contact->first_name = value;
                                        break;
                                        case 2:
                                                contact->last_name = value;
                                        break;

                                        case 3:
                                                contact->user_id = strtol(value,NULL,10);
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return contact;
}


Document* telegram_parse_document(char *str,int *count) {
        Document *document;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        document = calloc(2,sizeof(Document));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,document_names);
                                switch(c)       {
                                        case 0:
                                                document->file_id = value;
                                                i++;
                                        break;
                                        case 1:
                                                document->thumb = telegram_parse_photosize(value,&i);
                                                free(value);
                                        break;
                                        case 2:
                                                document->file_name = value;
                                                i++;
                                        break;

                                        case 3:
                                                document->mime_type = value;
                                                i++;
                                        break;

                                        case 4:
                                                document->file_size = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return document;
}

Video * telegram_parse_video(char *str,int *count)      {
        Video *video;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        video = calloc(2,sizeof(Video));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,video_names);
                                switch(c)       {
                                        case 0:
                                                video->file_id = value;
                                                i++;
                                        break;
                                        case 1:
                                                video->width = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 2:
                                                video->height = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 3:
                                                video->duration = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 4:
                                                video->thumb = telegram_parse_photosize(value,&i);
                                                free(value);
                                        break;
                                        case 5:
                                                video->mime_type = value;
                                                free(value);
                                                i++;
                                        break;
                                        case 6:
                                                video->file_size = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return video;
}

int telegram_init(char *token)  {
        int size;
        size = strlen(token);
        telegram_token = calloc(size,sizeof(char));
        if(telegram_token == NULL)      {
                fprintf(stderr, "calloc() failed\n");
                exit(1);
        }
        telegram_buffer = calloc(telegram_buffer_size,sizeof(char));
        if(telegram_buffer == NULL)     {
                fprintf(stderr, "calloc() failed\n");
                exit(1);
        }
        memcpy(telegram_token,token,size);
        return 0;
}

char *telegram_get_error()      {
        telegram_error = 0;
        return telegram_error_buffer;
}

int telegram_is_error() {
        return telegram_error;
}

char* telegram_build_post(char **variables,char **values)       {
        int i = 0,l = 0,size= 0,offset = 0;
        char *buffer = NULL;
        //printf("%X %X\n",variables,values);
        if(variables && values) {
                while( variables[l] && values[l])       {
                        //printf("%x %x\n",variables[l],values[l]);
                        size += (strlen(variables[l])+ strlen(values[l])+2);
                        l++;
                }
        }
        //printf("size = %i\nl = %i\n",size,l);
        buffer = calloc(size+1,sizeof(char));
        if(buffer)      {
                while(i<l)      {
                        if(i==0)        {
                                sprintf(buffer+offset,"%s=%s",variables[i],values[i]);
                                offset+= (1 +strlen(variables[i]) +strlen(values[i]));
                        }
                        else    {
                                sprintf(buffer+offset,"&%s=%s",variables[i],values[i]);
                                offset+= (1 +strlen(variables[i]) +strlen(values[i]));
                        }
                        i++;
                }
        }
        else    {
                fprintf(stderr,"error callo()");
                exit(0);
        }
        return buffer;
}

File* telegram_parse_file(char *str,int *count) {
        File *file;
        int r,n =1,c,i = 0;
        unsigned int state = 0,entrar = 1;
        char *variable,*value;
        file = calloc(2,sizeof(File));
        jsmntok_t *toks;
        jsmn_parser parser;
        toks = calloc(n+1,sizeof(jsmntok_t));
        r = telegram_jsmn_init(&parser,&toks,str,&n);
        while(entrar && i < r)  {
                switch(state)   {
                        case 0:
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 1:
                                variable = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                i++;
                        break;
                        case 2:
                                value = telegram_jsmn_get_token(toks[i],str);
                                state = message_states[state][toks[i].type];
                                c = indexOf(variable,file_names);
                                switch(c)       {
                                        case 0:
                                                file->file_id = value;
                                                i++;
                                        break;
                                        case 1:
                                                file->file_size = strtol(value,NULL,10);
                                                free(value);
                                                i++;
                                        break;
                                        case 2:
                                                file->file_path = value;
                                                free(value);
                                                i++;
                                        break;
                                        default:
                                                telegram_set_error("UNEXPECTED TOKEN VALUE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_VALUE);
                                                entrar = 0;
                                        break;
                                }
                                free(variable);
                        break;
                        case 4:
                                telegram_set_error("UNEXPECTED TOKEN TYPE",TELEGRAM_ERROR_UNEXPECTED_TOKEN_TYPE);
                                entrar = 0;
                        break;
                }
        }
        memset(toks,0,n*sizeof(jsmntok_t));
        free(toks);
        count[0]+=r;
        return file;

}

char* telegra_makeDownloadURL(File *file)       {
        char *url = NULL;
        char *temp = NULL;
        int l;
        int size_base;
        int size_token;
        int size_path;
        size_base = strlen(telegram_fileurl);
        size_token = strlen(telegram_token);
        size_path = strlen(file->file_path);
        l = size_base + size_token + size_path;
        temp = calloc(l+10,sizeof(char));
        if(temp)        {
                snprintf(temp,l+3,"%s%s/%s",telegram_fileurl,telegram_token,file->file_path);
                url = telegram_process_slash(temp);
                free(temp);
        }
        else    {
                fprintf(stderr,"calloc error\n");
                exit(1);
        }
        return url;
}

char* telegram_downloadFile(File *file,char *name)      {
        CURL *curl;
        CURLcode res;
        char *toreturn = NULL;
        FILE *toLocalFile = NULL;
        char **test = NULL;
        char *url = telegra_makeDownloadURL(file);
        curl = telegram_curl_init();
        curl_easy_setopt(curl, CURLOPT_URL, url);
        res = curl_easy_perform(curl);
        free(url);
        if(res == CURLE_OK)     {
                if(file->file_size == telegram_buffer_offset)   {
                        toLocalFile = fopen(name,"w");
                        if(toLocalFile) {
                                if(fwrite(telegram_buffer,sizeof(char),telegram_buffer_offset,toLocalFile) == telegram_buffer_offset)   {
                                        toreturn = name;
                                }
                                else    {
                                        telegram_set_error("stdio: fwrite()",-1000);
                                }
                                fclose(toLocalFile);
                        }
                        else    {
                                telegram_set_error("stdio: fopen()",-1000);
                        }
                        telegram_reset_buffer();
                }
                else    {
                        printf("Diff %i %i\n",file->file_size,telegram_buffer_offset);
                }
                curl_easy_cleanup(curl);
        }
        else    {
                telegram_set_error("curl: curl_easy_perform()",-1000);
        }
        return toreturn;
}

char* telegram_process_slash(char *str) {
        int i = 0,j =0;
        char *temp = NULL;
        if(str) {
                temp = calloc(strlen(str)+2,sizeof(char));
                while(str[j] != 0)      { // '\0'
                        if(str[j] == '\\')
                                j++;
                        temp[i] = str[j];
                        i++;
                        j++;
                }
        }
        else    {
                telegram_set_error("NULL funtion argument",-10);
        }
        return temp;
}

CURL* telegram_curl_init()      {
        CURL *curl  = NULL;
        //printf("CURL INIT\n");
        curl_global_init(CURL_GLOBAL_DEFAULT);
        curl = curl_easy_init();
        if(curl) {
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
                curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);
        }
        return curl;
}

Updates* telegram_free_updates(Updates *updates)        {
        if(updates)     {
                int i = 0;
                while(i < updates->length)      {
                        if(updates->list[i])
                                telegram_free_update(updates->list[i]);
                        i++;
                }
                memset(updates,0,sizeof(Updates));
                free(updates);
        }
        return NULL;
}

Update* telegram_free_update(Update *update)    {
        if(update)      {
                switch(update->type)    {
                        case 0:
                                telegram_free_message(update->item.message);
                        break;
                }
                memset(update,0,sizeof(Update));
                free(update);
        }
        return NULL;
}

Message* telegram_free_message(Message *message)        {
        if(message)     {
                if(message->from)       {
                        telegram_free_user(message->from);
                }
                if(message->chat)       {
                        telegram_free_chat(message->chat);
                }
                if(message->forward_from)       {
                        telegram_free_user(message->forward_from);
                }
                if(message->reply_to_message)   {
                        telegram_free_message(message->reply_to_message);
                }
                if(message->audio)      {
                        telegram_free_audio(message->audio);
                }
                if(message->document)   {
                        telegram_free_document(message->document);
                }
                if(message->photo)      {
                        telegram_free_photos(message->photo);
                }
                if(message->sticker)    {
                        telegram_free_sticker(message->sticker);
                }
                if(message->video)      {
                        telegram_free_video(message->video);
                }
                if(message->voice)      {
                        telegram_free_voice(message->voice);
                }
                if(message->contact)    {
                        telegram_free_contact(message->contact);
                }
                if(message->location)   {
                        telegram_free_location(message->location);
                }
                if(message->new_chat_participant)       {
                        telegram_free_user(message->new_chat_participant);
                }
                if(message->left_chat_participant)      {
                        telegram_free_user(message->left_chat_participant);
                }
                if(message->new_chat_photo)     {
                        telegram_free_photos(message->new_chat_photo);
                }
                memset(message,0,sizeof(Message));
                free(message);
        }
        return NULL;
}

Location* telegram_free_location(Location *location)    {
        if(location)    {
                memset(location,0,sizeof(Location));
                free(location);
        }
        return NULL;
}

Voice* telegram_free_voice(Voice *voice)        {
        if(voice)       {
                if(voice->file_id)      {
                        free(voice->file_id);
                }
                if(voice->mime_type)    {
                        free(voice->mime_type);
                }
                memset(voice,0,sizeof(Voice));
                free(voice);
        }
        return NULL;
}

Contact* telegram_free_contact(Contact *contact)        {
        if(contact)     {
                if(contact->phone_number)       {
                        free(contact->phone_number);
                }
                if(contact->first_name) {
                        free(contact->first_name);
                }
                if(contact->last_name)  {
                        free(contact->last_name);
                }
                memset(contact,0,sizeof(Contact));
                free(contact);
        }
        return NULL;
}

Document* telegram_free_document(Document *document)    {
        if(document)    {
                if(document->file_id)   {
                        free(document->file_id);
                }
                if(document->mime_type) {
                        free(document->mime_type);
                }
                if(document->file_name) {
                        free(document->file_name);
                }
                if(document->thumb)     {
                        telegram_free_photosize(document->thumb);
                }
                memset(document,0,sizeof(Document));
                free(document);
        }
        return NULL;
}

Chat* telegram_free_chat(Chat *chat)    {
        if(chat)        {
                if(chat->title) {
                        free(chat->title);
                }
                if(chat->username)      {
                        free(chat->username);
                }
                if(chat->first_name)    {
                        free(chat->first_name);
                }
                if(chat->last_name)     {
                        free(chat->last_name);
                }
                memset(chat,0,sizeof(Chat));
                free(chat);
        }
        return NULL;
}

Audio* telegram_free_audio(Audio *audio)        {
        if(audio)       {
                if(audio->file_id)      {
                        free(audio->file_id);
                }
                if(audio->performer)    {
                        free(audio->performer);
                }
                if(audio->title)        {
                        free(audio->title);
                }
                if(audio->mime_type)    {
                        free(audio->mime_type);
                }
                memset(audio,0,sizeof(Audio));
                free(audio);
        }
        return NULL;
}

Sticker* telegram_free_sticker(Sticker *sticker)        {
        if(sticker)     {
                if(sticker->file_id)    {
                        free(sticker->file_id);
                }
                if(sticker->thumb)      {
                        telegram_free_photosize(sticker->thumb);
                }
                memset(sticker,0,sizeof(Sticker));
                free(sticker);
        }
        return NULL;
}

PhotoSize* telegram_free_photosize(PhotoSize *photosize)        {
        if(photosize)   {
                if(photosize->file_id)  {
                        free(photosize->file_id);
                }
                memset(photosize,0,sizeof(PhotoSize));
                free(photosize);
        }
        return NULL;
}

Photos* telegram_free_photos(Photos *photos)    {
        int i = 0;
        if(photos)      {
                while(i < photos->length)       {
                        if(photos->item[i])
                                telegram_free_photosize(photos->item[i]);
                        i++;
                }
                free(photos->item);
                memset(photos,0,sizeof(Photos));
                free(photos);
        }
        return NULL;
}

Video* telegram_free_video(Video *video)        {
        if(video)       {
                if(video->file_id)      {
                        free(video->file_id);
                }
                if(video->mime_type)    {
                        free(video->mime_type);
                }
                if(video->thumb)        {
                        telegram_free_photosize(video->thumb);
                }
                memset(video,0,sizeof(Video));
                free(video);
        }
        return NULL;
}

Message* telegram_sendMessage(char *postdata)   {
        CURL *curl = NULL;
        CURLcode res;
        Response *response = NULL;
        Message *message = NULL;
        int i;
        char *url = NULL;
        url = telegram_makeurl("/sendMessage");
        curl = telegram_curl_init();
        curl_easy_setopt(curl, CURLOPT_URL , url);
        curl_easy_setopt(curl,  CURLOPT_POSTFIELDS , postdata);
        res = curl_easy_perform(curl);
        free(url);
        if(res == CURLE_OK)     {
                response = telegram_parse_response(telegram_buffer,&i);
                if(!telegram_error)     {
                        message = telegram_parse_message(response->result,&i);
                }
                telegram_free_response(response);
                telegram_reset_buffer();
                curl_easy_cleanup(curl);
        }
        else    {
                telegram_set_error("curl: curl_easy_perform()",-1000);
        }
        return message;
}

Message* telegram_sendDocument(char *filename,char **variables, char **valores) {
        CURL *curl = NULL;
        CURLcode res;
        struct curl_httppost *formpost=NULL;
        struct curl_httppost *lastptr=NULL;
        struct curl_slist *headerlist=NULL;
        static const char buf[] = "Expect:";
        Response *response = NULL;
        Message *message = NULL;
        char *url = NULL;
        int i;
        if(filename){
                url = telegram_makeurl("/sendDocument");
                curl = telegram_curl_init();
                i = 0;
                while(variables[i] != NULL && valores[i] != NULL)       {
                        curl_formadd(&formpost,&lastptr,CURLFORM_COPYNAME, variables[i],CURLFORM_COPYCONTENTS, valores[i],CURLFORM_END);
                        i++;
                }
                curl_formadd(&formpost,&lastptr,CURLFORM_COPYNAME, "document",CURLFORM_FILE, filename,CURLFORM_END);
                headerlist = curl_slist_append(headerlist, buf);
                curl_easy_setopt(curl, CURLOPT_URL , url);
                curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
                curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
                res = curl_easy_perform(curl);
                if(res == CURLE_OK)     {
                        response = telegram_parse_response(telegram_buffer,&i);
                        if(!telegram_error)     {
                                message = telegram_parse_message(response->result,&i);
                        }
                        else    {
                                telegram_set_error(response->description,1);
                        }
                        free(url);
                        curl_easy_cleanup(curl);
                        curl_formfree(formpost);
                        curl_slist_free_all (headerlist);
                }
                else    {
                        telegram_set_error("curl",1);
                }

        }
        else    {
                telegram_set_error("NULL argument",1);
        }
        return  message;
}

Message* sendLocation(char postdata)    {
        CURL *curl = NULL;
        CURLcode res;
        Response *response = NULL;
        Message *message = NULL;
        int i;
        char *url = NULL;
        url = telegram_makeurl("/sendLocation");
        curl = telegram_curl_init();
        curl_easy_setopt(curl, CURLOPT_URL , url);
        curl_easy_setopt(curl,  CURLOPT_POSTFIELDS , postdata);
        res = curl_easy_perform(curl);
        free(url);
        if(res == CURLE_OK)     {
                response = telegram_parse_response(telegram_buffer,&i);
                if(!telegram_error)     {
                        message = telegram_parse_message(response->result,&i);
                }
                telegram_free_response(response);
                telegram_reset_buffer();
                curl_easy_cleanup(curl);
        }
        else    {
                telegram_set_error("curl: curl_easy_perform()",-1000);
        }
        return message;

}