Visualizzazione risultati 1 fino 15 di 15

Discussione: [Telegram BOT] cURL limitato a 400 Kib?

  1. #1
    Guest

    Question [Telegram BOT] cURL limitato a 400 Kib?

    Ho scritto la demo d'un BOT per Telegram, molto elementare, per delle amiche.
    Inizialmente lo avevo fatto in Python, quindi l'ho convertito in PHP.

    Lo scopo del BOT è inviare immagini.
    Mentre la versione in Python non pare avere alcun problema (né in locale, anche con una ADSL 2 Mbps/1 Mbps, né su Amazon AWS EC2), quella in PHP, su Altervista, non invia alcune immagini.
    Dei 6 file che uso per le prove, la discriminante pare essere la dimensione: le 3 più piccole (fino a 331 KiB) vengono mandate, le 3 più grandi (da 467 KiB) no.
    Le risposta HTTP di api.telegram.org è sempre 200, anche quando l'immagine non viene trasmessa.

    L'account è sbloccato per le connessioni server to server ("Collegamento esterno senza restrizioni") e non sono a corto di risorse (0.1% di spazio occupato e 0.0% di banda consumata).

    Queste è il contenuto del file .htaccess, in ogni folder.
    <<
    # # av:php5-engine
    AddHandler av-php56 .php

    php_value post_max_size 10M
    php_value upload_max_filesize 10M
    php_value max_file_uploads 10
    php_value max_input_time 0
    php_value max_execution_time 60
    >>

    Per inviare le immagini via cURL, infine, ho impostato questi paramentri.
    CURLOPT_RETURNTRANSFER => True
    CURLOPT_CONNECTTIMEOUT => 300
    CURLOPT_TIMEOUT => 300

    Dove sto sbagliando?
    Ultima modifica di keliarbot : 14-03-2017 alle ore 12.13.10 Motivo: Test #0.

  2. #2
    darbula non è connesso AlterGuru 2500
    Data registrazione
    24-04-2011
    Messaggi
    2,894

    Predefinito

    La url dopo si trasforma in https:// disabilita il certificato e la verifica del dominio e vedi followlocation se è abilitato
    Ultima modifica di darbula : 14-03-2017 alle ore 12.37.31

  3. #3
    Guest

    Predefinito

    Intanto grazie per il feedback.


    HTTPS è attivo nell'account ed usato nella script PHP (non l'ho indicato, perché credevo che non fosse possibile fare diversamente).
    Tanto per capirci, questa è la URL che viene invocata per inviare le immagini.
    https://api.telegram.org/bot{TOKEN}/sendPhoto?chat_id={ID_UTENTE}

    CURLOPT_FOLLOWLOCATION ho provato ad abilitarlo, ma non è cambiato nulla (d'altro canto, non ho mai ricevuto un codice HTTP 3xx).

    A pranzo vedrò come disabilitare certificato e verifica del dominio.

  4. #4
    darbula non è connesso AlterGuru 2500
    Data registrazione
    24-04-2011
    Messaggi
    2,894

    Predefinito

    prego figurati si condivide è proprio questo lo scopo di un forum.. Qui le direttive .htaccess sono ereditate, si posso utilizzare solo le porte standard (80 e 443) uhm se è abilitato il followcation viene effettuato il redirect lo stato http sarà di quest'ultimo .. beh le cose da disattivare le trovi sempre qui
    http://php.net/manual/en/function.curl-setopt.php non ti faccio un copia incolla solo perché vedo che hai le basi per programmare e quindi devi ragionare con la tua testa e non la mia, il valore di CURLOPT_POSTFIELDS è un array, giusto?

  5. #5
    Guest

    Predefinito

    Omettendo i controlli sui certificati SSL ho ottenuto un miglioramento delle prestazioni: i tempi di risposta (per le immagini che funzionano) sono ora analoghi a quelli della versione in Python.
    Il problema originale è rimasto però immutato.

    Proverò ad usare immagini differenti (sperando di ottenere nuove informazioni) ed a testare la script con altri hosting.


    Per la cronaca, questo è l'elenco completo delle impostazioni che sto usando ora.

    PHP => 5.6
    curl_init => "https://api.telegram.org/bot{TOKEN}/sendPhoto?chat_id={ID_UTENTE}"

    CURLOPT_FAILONERROR => True
    CURLOPT_RETURNTRANSFER => True
    CURLOPT_CONNECTTIMEOUT => 15
    CURLOPT_TIMEOUT => 300
    CURLOPT_FOLLOWLOCATION => False
    CURLOPT_SSL_VERIFYHOST => 0
    CURLOPT_SSL_VERIFYPEER => False
    CURLOPT_HTTPHEADER => array("Content-Type: multipart/form-data")
    CURLOPT_POSTFIELDS => array("chat_id" => {ID_UTENTE}, "photo" => new CURLFile({REAL_PATH}))

  6. #6
    darbula non è connesso AlterGuru 2500
    Data registrazione
    24-04-2011
    Messaggi
    2,894

    Predefinito

    direttive che accetta altervista http://it.help.altervista.org/w/Conf...ta_(.htaccess) manca l'opzione post abilitata, dovremmo abilitare gli errori metti in cima tutto questo error_reporting(E_ALL | E_NOTICE | E_STRICT | E_DEPRECADED);
    ini_set("display_errors" , "stdout");
    ini_set("display_startup_errors" , 1); e controlliamo gli errori di curl http://php.net/manual/en/function.curl-error.php cioè devi modificare lo script.php in modo che uploadi i file nel tuo spazio e riveli gli eventuali errori sempre in script.php.. (non fare troppe richieste,altrimenti ti bloccano l'account e devi chiedere lo sblocco) il prossimo passo sarà pensare a telegram
    Ultima modifica di darbula : 14-03-2017 alle ore 22.36.57

  7. #7
    Guest

    Predefinito

    Ho rivisto il file .htaccess, in base al documento di Altervista: non ho ottenuto nulla, però ho preferito rimuovere un parametro non indicato (max_file_uploads) ed alzare gli altri, in base ai valori previsti (ero stato troppo restrittivo).


    A parte questo, ho aggiunto le istruzioni per il debug che mi hai suggerito.
    A differenza di prima, ora riesco a vedere gli errori a schermo (non ce n'erano, ma ne ho introdotto uno per verificare): prima consultavo un log su disco, ma ovviamente dovevo sempre sperare d'aver intercettato gli errori, essendo una soluzione custom...

    Ciò che mi lascia perplesso, è che simulando l'azione non funzionante continuo a non ricevere alcun errore: né nel log (cosa che già sapevo), né a schermo.
    In pratica ho fatto in modo che, chiamando la script da browser, questa tenti d'inviarmi l'immagine, bypassando quindi il webhook. Ovviamente, ho fatto anche in modo che m'invii 1 messaggio di testo (me lo invia) ed 1 delle altre immagini (me la invia), per essere certo che non ci fossero regressioni.

  8. #8
    darbula non è connesso AlterGuru 2500
    Data registrazione
    24-04-2011
    Messaggi
    2,894

    Predefinito

    Scusami temo di non aver capito nulla.. Mi posti lo script completo? Anche se non lo posso provare almeno lo analizzo. (lo script modificato)

  9. #9
    Guest

    Predefinito

    https://keliarbot.altervista.org/demo/debug.php
    Ho tolto la logica applicativa e lasciato solo le chiamate dirette: 1 messaggio di testo e 2 immagini (tutte verso un mio account).
    Volendola testare su un altro server, basterebbe inserire il token d'un BOT e correggere i puntamenti alle immagini.

    <EDIT>
    Per completezza, queste sono le 2 immagini usate in questo test: dato che il problema si verifica con file specifici, ha senso prenderle in considerazione.
    Funziona.
    Non funziona.
    </EDIT>

    Codice PHP:
    <?php
    error_reporting
    (E_ALL | E_NOTICE | E_STRICT);
    ini_set("display_errors", "stdout");
    ini_set("display_startup_errors", 1);

    define("BOT_TOKEN", "{BOT_TOKEN}");
    define("API_URL", "https://api.telegram.org/bot".BOT_TOKEN."/");

    function
    exec_curl_request($handle) {
    $response = curl_exec($handle);

    if (
    $response === false) {
    $errno = curl_errno($handle);
    $error = curl_error($handle);
    error_log("Curl returned error {$errno}: {$error}.\n");
    curl_close($handle);
    return
    false;
    }

    $http_code = intval(curl_getinfo($handle, CURLINFO_HTTP_CODE));
    curl_close($handle);

    $logFile = "log/".date("Ymd");
    //$logHandler = fopen($logFile, "a");
    //fwrite($logHandler, date("Y-m-d H:i:s P")." - INFO - HTTP code: ".$http_code.".\n");
    //fclose($logHandler);
    if ($http_code >= 500) {
    $logHandler = fopen($logFile, "a");
    fwrite($logHandler, date("Y-m-d H:i:s P")." - ERROR - HTTP code: ".$http_code.".\n");
    fclose($logHandler);
    sleep(10);
    return
    false;
    } else if (
    $http_code != 200) {
    $response = json_decode($response, True);
    error_log("Request has failed with error {$response["error_code"]}: {$response["description"]}.\n");
    $logHandler = fopen($logFile, "a");
    fwrite($logHandler, date("Y-m-d H:i:s P")." - ERROR - Request has failed with error {$response["error_code"]}: {$response["description"]}.\n");
    fclose($logHandler);
    if (
    $http_code == 401) {
    throw new
    Exception("Invalid access token provided");
    }
    return
    false;
    } else {
    $response = json_decode($response, True);
    if (isset(
    $response["description"])) {
    error_log("Request was successfull: {$response["description"]}.\n");
    }
    $response = $response["result"];
    }

    return
    $response;
    }

    function
    apiRequest($method, $parameters) {
    if (!
    is_string($method)) {
    error_log("Method name must be a string.\n");
    return
    false;
    }

    if (!
    $parameters) {
    $parameters = array();
    } else if (!
    is_array($parameters)) {
    error_log("Parameters must be an array.\n");
    return
    false;
    }

    foreach (
    $parameters as $key => &$val) {
    if (!
    is_numeric($val) && !is_string($val)) {
    $val = json_encode($val);
    }
    }
    $url = API_URL.$method."?".http_build_query($parameters);

    $handle = curl_init($url);
    curl_setopt($handle, CURLOPT_FAILONERROR, True);
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, True);
    curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
    curl_setopt($handle, CURLOPT_TIMEOUT, 60);
    curl_setopt($handle, CURLOPT_FOLLOWLOCATION, False);

    return
    exec_curl_request($handle);
    }

    function
    apiRequestImage($type, $parameters) {
    if (!
    $parameters) {
    $parameters = array();
    } else if (!
    is_array($parameters)) {
    error_log("Parameters must be an array.\n");
    return
    false;
    }

    $url = API_URL."sendPhoto?chat_id=".$parameters["chat_id"];

    $handle = curl_init($url);
    curl_setopt($handle, CURLOPT_FAILONERROR, True);
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, True);
    curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 15);
    curl_setopt($handle, CURLOPT_TIMEOUT, 300);
    curl_setopt($handle, CURLOPT_FOLLOWLOCATION, False);
    //curl_setopt($handle, CURLOPT_SSL_VERIFYSTATUS, False);
    curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, False);
    curl_setopt($handle, CURLOPT_POSTFIELDS, $parameters);
    switch (
    $type) {
    case
    "jpeg":
    case
    "jpg":
    curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: multipart/form-data"));
    break;
    case
    "png":
    curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: multipart/form-data"));
    break;
    case
    "gif":
    curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: multipart/form-data"));
    break;
    default:
    curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: multipart/form-data"));
    }

    return
    exec_curl_request($handle);
    }



    $content = file_get_contents("php://input");
    $update = json_decode($content, True);
    apiRequest("sendMessage", array("chat_id" => "248604001", "text" => "Oh, yeah! ".json_decode('"\uD83D\uDC44"')));
    apiRequestImage("png", array("chat_id" => "248604001", "photo" => new CURLFile(realpath("prizes/Wallpaper_Spada_destra_1920x1080.png"))));
    apiRequestImage("png", array("chat_id" => "248604001", "photo" => new CURLFile(realpath("prizes/Pagliacci.png"))));

    if (!
    $update) {
    exit;
    }

    if (isset(
    $update["message"])) {
    processMessage($update["message"]);
    }
    ?>
    Ultima modifica di keliarbot : 15-03-2017 alle ore 01.11.47 Motivo: Aggiunti i puntamenti diretti alle immagini.

  10. #10
    darbula non è connesso AlterGuru 2500
    Data registrazione
    24-04-2011
    Messaggi
    2,894

    Smile

    a prima occhiata, manca sempre l'option CURLOPT_POST TRUE se manca questo parametro la richiesta dovrebbe essere get e leggi come resettare poi il post (nel caso dovessi fare una chiamata get) CURLOPT_HTTPGET TRUE e disabilito l'invio di header (qualche server potrebbe inviarli mentre servono solo i dati post) CURLOPT_HEADER FALSE
    php://input non legge i dati da enctype="multipart/form-data" ne consengue che non si possono inviare oggetti, ma la sola forma "name=io+tu" (il contenuto di $_POST['name'] è "io tu").
    Ultima modifica di darbula : 15-03-2017 alle ore 23.11.07

  11. #11
    Guest

    Lightbulb

    Ho risolto il problema, ma non ho corretto l'errore: invece che mandare il file, mando la sua URL. ^^''

    Probabilmente sto veramente sbagliando ad usare il POST, ma nonostante diverse correzioni (vedi sotto) il risultato non è mai cambiato.
    Nel codice che segue, della I immagine (una di quelle che non funzionavano) viene solo indicata la sua URL, mentre la II immagine (una di quelle che hanno sempre funzionato) viene inviata come oggetto.

    Codice PHP:
    <?php
    error_reporting
    (E_ALL | E_NOTICE | E_STRICT);
    ini_set("display_errors", "stdout");
    ini_set("display_startup_errors", 1);

    define("BOT_TOKEN", "{BOT_TOKEN}");
    define("API_URL", "https://api.telegram.org/bot".BOT_TOKEN."/");
    define("CURRENT_PATH", (isset($_SERVER['HTTPS'])?"https":"http")."://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]");

    function
    exec_curl_request($handle) {
    $response = curl_exec($handle);

    if (
    $response === false) {
    $errno = curl_errno($handle);
    $error = curl_error($handle);
    error_log("Curl returned error {$errno}: {$error}.\n");
    curl_close($handle);
    return
    false;
    }

    $http_code = intval(curl_getinfo($handle, CURLINFO_HTTP_CODE));
    curl_close($handle);

    if (
    $http_code >= 500) {
    sleep(10);
    return
    false;
    } else if (
    $http_code != 200) {
    $response = json_decode($response, True);
    error_log("Request has failed with error {$response["error_code"]}: {$response["description"]}.\n");
    if (
    $http_code == 401) {
    throw new
    Exception("Invalid access token provided");
    }
    return
    false;
    } else {
    $response = json_decode($response, True);
    if (isset(
    $response["description"])) {
    error_log("Request was successfull: {$response["description"]}.\n");
    }
    $response = $response["result"];
    }

    return
    $response;
    }

    function
    apiRequestImage($parameters) {
    if (!
    $parameters) {
    $parameters = array();
    } else if (!
    is_array($parameters)) {
    error_log("Parameters must be an array.\n");
    return
    false;
    }

    $url = API_URL."sendPhoto";

    $handle = curl_init($url);
    curl_setopt($handle, CURLOPT_FAILONERROR, True);
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, True);
    curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 15);
    curl_setopt($handle, CURLOPT_TIMEOUT, 300);
    curl_setopt($handle, CURLOPT_FOLLOWLOCATION, False);
    curl_setopt($handle, CURLOPT_POST, True);
    curl_setopt($handle, CURLOPT_HEADER, False);
    //curl_setopt($handle, CURLOPT_SSL_VERIFYSTATUS, False);
    curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, False);
    curl_setopt($handle, CURLOPT_POSTFIELDS, $parameters);

    return
    exec_curl_request($handle);
    curl_setopt($handle, CURLOPT_HTTPGET, True);
    curl_setopt($handle, CURLOPT_HEADER, True);
    }



    $content = file_get_contents("php://input");
    $update = json_decode($content, True);
    apiRequestImage(array("chat_id" => "248604001", "photo" => substr(CURRENT_PATH, 0, strrpos(CURRENT_PATH, "/")+1)."prizes/Pagliacci.png", "disable_notification" => True));
    apiRequestImage(array("chat_id" => "248604001", "photo" => new CURLFile(realpath("prizes/Wallpaper_Spada_destra_1920x1080.png"), "multipart/form-data"), "disable_notification" => True));

    if (!
    $update) {
    exit;
    }

    if (isset(
    $update["message"])) {
    processMessage($update["message"]);
    }
    ?>

  12. #12
    darbula non è connesso AlterGuru 2500
    Data registrazione
    24-04-2011
    Messaggi
    2,894

    Predefinito

    Beh ne sono convinto anch'io, ma al momento ho uno schermo piccolissimo per capire come funziona il codice, cmq. usa gmdate per la data corrente, perché date e similari sono influenzati dal fuso orario , ammettendo che sia in uso il fuso orario italiano la data risulterebbe meno 1 o 2 ore.

  13. #13
    Guest

    Predefinito

    Dato che Altervista ha le macchine in Italia, ho usato date proprio per avere l'orario italiano.
    Chiaramente ho inserito nel log anche il fuso orario (P), così da evitare ambiguità.

    Il log verrà consultato da persone "non tecniche", così ho voluto che fosse il più possibile user friendly.
    Dal momento che il BOT verifica l'id dell'utente (per essere certo che sia in regola con l'abbonamento), se il cliente è un cerebroleso (e quelli italiani lo sono quasi sempre), la tizia deve potersi arrangiare coi log.

  14. #14
    darbula non è connesso AlterGuru 2500
    Data registrazione
    24-04-2011
    Messaggi
    2,894

    Predefinito

    vedi se ci capisci qualcosa sulla specifica upload html (fa degli esempi con enctype multipart/form-data) mi dispiace più di così non posso aiutarti https://www.ietf.org/rfc/rfc1867.txt
    Il mio consiglio sarebbe di concentrarsi solo sull'upload senza passare da telegram in modo da replicare un browser .
    EDIT: Nel file php ricevente userai il print di $_POST e il controllo degli errori di $_FILES
    http://php.net/manual/en/features.fi...d.multiple.php cmq. ti consiglio di rivedere tutte e tre le proprietà risorsa,mime type, name http://php.net/manual/en/class.curlfile.php
    ho provato ad inviare un'immagine di 480 kilobyte nel mio spazio e non riscontro alcun problemascript.php
    Codice PHP:
    <?php
    $ch
    = curl_init('http://percorso/upload.php');

    // Create a CURLFile object
    $cfile = new CURLFile('earth.gif','image/gif','test_name');

    // Assign POST data
    $data = array('test_file' => $cfile);
    curl_setopt($ch, CURLOPT_POST,1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

    // Execute the handle
    curl_exec($ch);
    ?>
    upload.php
    Codice PHP:
    <?php var_dump($_FILES); ?>
    Ultima modifica di darbula : 16-03-2017 alle ore 04.27.26

  15. #15
    Guest

    Predefinito

    Ovviamente ti ringrazio, però non farò nuove prove prima del weekend: dovrò concentrarmi sulla distribuzione ibrida (photo e/o video), in funzione delle abilitazioni dal cliente.
    Occupandomene a tempo perso, mi ci vorranno 1 o 2 giorni... anche perché preferisco tenere allineata la versione Python (dovemmo fare un monumento a Mondadori, però Amazon è un altro pianeta e 5 €/mese sono ammortizzabili).

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •