This function should be called from the bot implementation callback. * If the bot request has a file (the user can see that by inspecting * the br->file_type field), then this function will attempt to download * the file from Telegram and store it in the current working directory * with the name 'br->file_id'. * * On success 1 is returned, otherwise 0. * When the function returns successful
| 497 | * When the function returns successfully, the caller can access |
| 498 | * a file named 'br->file_id'. */ |
| 499 | int botGetFile(BotRequest *br, const char *target_filename) { |
| 500 | /* 1. Get the file information and path. */ |
| 501 | char *options[2]; |
| 502 | options[0] = "file_id"; |
| 503 | options[1] = br->file_id; |
| 504 | |
| 505 | int res; |
| 506 | sds body = makeGETBotRequest("getFile",&res,options,1); |
| 507 | if (res == 0) { |
| 508 | sdsfree(body); |
| 509 | return 0; // Error. |
| 510 | } |
| 511 | |
| 512 | cJSON *json = cJSON_Parse(body); |
| 513 | cJSON *result = cJSON_Select(json,".result.file_path:s"); |
| 514 | char *file_path = result ? result->valuestring : NULL; |
| 515 | sdsfree(body); |
| 516 | if (!file_path) { |
| 517 | cJSON_Delete(json); |
| 518 | return 0; |
| 519 | } |
| 520 | |
| 521 | /* 2. Get the file content. */ |
| 522 | CURL* curl = curl_easy_init(); |
| 523 | if (!curl) { |
| 524 | cJSON_Delete(json); |
| 525 | return 0; |
| 526 | } |
| 527 | |
| 528 | /* We need to open a file for writing. We will be |
| 529 | * using the curl callback in order to append to the |
| 530 | * file. */ |
| 531 | const char *filename = target_filename ? target_filename : br->file_id; |
| 532 | FILE *fp = fopen(filename, "w"); |
| 533 | if (fp == NULL) { |
| 534 | cJSON_Delete(json); |
| 535 | curl_easy_cleanup(curl); |
| 536 | return 0; |
| 537 | } |
| 538 | |
| 539 | char url[1024]; |
| 540 | snprintf(url, sizeof(url), |
| 541 | "https://api.telegram.org/file/bot%s/%s", Bot.apikey, file_path); |
| 542 | cJSON_Delete(json); |
| 543 | curl_easy_setopt(curl, CURLOPT_URL, url); |
| 544 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, makeHTTPGETCallWriterFILE); |
| 545 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fp); |
| 546 | curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); |
| 547 | curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1L); |
| 548 | curl_easy_setopt(curl, CURLOPT_TIMEOUT, 15); |
| 549 | curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15); |
| 550 | |
| 551 | /* Perform the request and cleanup. */ |
| 552 | int retval = curl_easy_perform(curl) == CURLE_OK ? 1 : 0; |
| 553 | curl_easy_cleanup(curl); |
| 554 | fclose(fp); |
| 555 | /* Best effort removal of incomplete file. */ |
| 556 | if (retval == 0) unlink(filename); |
no test coverage detected