skip to Main Content

The sendPhoto command require an argument photo defined as InputFile or String.

The API doc tells:

Photo to send. You can either pass a file_id as String to resend a photo
that is already on the Telegram servers, or upload a new photo using
multipart/form-data.

And

InputFile

This object represents the contents of a file to be uploaded. Must be
posted using multipart/form-data in the usual way that files are 
uploaded via the browser. 

So I tried this method

    $bot_url    = "https://api.telegram.org/bot<bot_id>/";
    $url = $bot_url . "sendPhoto?chat_id=" . $chat_id;
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        "Content-Type:multipart/form-data"
    ));
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, array(
        "photo"     => "@/path/to/image.png", 
    )); 
    curl_setopt($ch, CURLOPT_INFILESIZE, filesize("/root/dev/fe_new.png"));
    $output = curl_exec($ch);

The curls is executed, but Telegram reply this to me:

Error: Bad Request: Wrong persistent file_id specified: contains wrong
characters or have wrong length

I also tried replacing @/path... with a file_get_contents, but in this case Telegram give me an empty reply (and curl_error is empty !).

What the way to send a photo to telegram using php + curl ?

7

Answers


  1. Chosen as BEST ANSWER

    This is my working solution, but it requires PHP 5.5:

    $bot_url    = "https://api.telegram.org/bot<bot_id>/";
    $url        = $bot_url . "sendPhoto?chat_id=" . $chat_id ;
    
    $post_fields = array('chat_id'   => $chat_id,
        'photo'     => new CURLFile(realpath("/path/to/image.png"))
    );
    
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        "Content-Type:multipart/form-data"
    ));
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields); 
    $output = curl_exec($ch);
    

  2. You can use this API: https://github.com/mgp25/Telegram-Bot-API

    example:

    $tg->sendPhoto($chat_id, $image, $caption);
    

    You can use either a stored image or URL.

    Login or Signup to reply.
  3. I searched a lot online but didn’t find the answer. But, your question solved my problem … I just changed your code and that answered it for me …
    I changed your code to this:

    $chat_id=chat Id Here;
    
    $bot_url    = "https://api.telegram.org/botYOUR_BOT_TOKEN/";
    $url = $bot_url . "sendPhoto?chat_id=" . $chat_id;
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        "Content-Type:multipart/form-data"
    ));
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, array(
        "photo"     => "@path/to/image.png", 
    )); 
    curl_setopt($ch, CURLOPT_INFILESIZE, filesize("path/to/image.png"));
    $output = curl_exec($ch);
    print$output;
    
    Login or Signup to reply.
  4. This code helps me alot which I get from php.net website here

    Visit http://php.net/manual/en/class.curlfile.php#115161
    (Vote Up this code in php website).

    I just change headers in this code for telegram bot to send image just copy this function

    function curl_custom_postfields($ch, array $assoc = array(), array $files = array()) {
    
              // invalid characters for "name" and "filename"
              static $disallow = array("", """, "r", "n");
    
              // build normal parameters
              foreach ($assoc as $k => $v) {
                  $k = str_replace($disallow, "_", $k);
                  $body[] = implode("rn", array(
                      "Content-Disposition: form-data; name="{$k}"",
                      "",
                      filter_var($v),
                  ));
              }
    
              // build file parameters
              foreach ($files as $k => $v) {
                  switch (true) {
                      case false === $v = realpath(filter_var($v)):
                      case !is_file($v):
                      case !is_readable($v):
                          continue; // or return false, throw new InvalidArgumentException
                  }
                  $data = file_get_contents($v);
                  $v = call_user_func("end", explode(DIRECTORY_SEPARATOR, $v));
                  $k = str_replace($disallow, "_", $k);
                  $v = str_replace($disallow, "_", $v);
                  $body[] = implode("rn", array(
                      "Content-Disposition: form-data; name="{$k}"; filename="{$v}"",
                      "Content-Type: image/jpeg",
                      "",
                      $data,
                  ));
              }
    
              // generate safe boundary
              do {
                  $boundary = "---------------------" . md5(mt_rand() . microtime());
              } while (preg_grep("/{$boundary}/", $body));
    
              // add boundary for each parameters
              array_walk($body, function (&$part) use ($boundary) {
                  $part = "--{$boundary}rn{$part}";
              });
    
              // add final boundary
              $body[] = "--{$boundary}--";
              $body[] = "";
    
              // set options
              return @curl_setopt_array($ch, array(
                  CURLOPT_POST       => true,
                  CURLOPT_POSTFIELDS => implode("rn", $body),
                  CURLOPT_HTTPHEADER => array(
                      "Expect: 100-continue",
                      "Content-Type: multipart/form-data; boundary={$boundary}", // change Content-Type
                  ),
              ));
          }
    

    Basic Try:Now just use this code by sending photo name with path and chat id
    here is it how:-

    $array1=array('chat_id'=><here_chat_id>);
    $array2=array('photo'=>'index.jpg') //path
    $ch = curl_init();       
    curl_setopt($ch, CURLOPT_URL,"https://api.telegram.org/<bot_token>/sendPhoto");
    curl_custom_postfields($ch,$array1,$array2);//above custom function
    $output=curl_exec($ch);
    close($ch);
    

    For sending png or other methods change curl_custom function according to your need.

    Login or Signup to reply.
  5. This a bad idea, but you can use some like that:

    #!/bin/bash
    
    set -x
    set -e
    
    BDIR=/tmp/${RANDOM}
    TG_TOKEN=""
    TG_CHAT_ID=
    
    mkdir -p ${BDIR}
    chmod -R 777 ${BDIR}
    su postgres -c "pg_dumpall -f ${BDIR}/postgre.sql"
    tar czf ${BDIR}/${HOSTNAME}.tar.gz /var/lib/grafana/ /etc/grafana/ ${BDIR}/postgre.sql
    
    
    curl -F caption="$(date)" -F chat_id="${TG_CHAT_ID}" -F document=@"${BDIR}/${HOSTNAME}.tar.gz" https://api.telegram.org/bot${TG_TOKEN}/sendDocument
    
    rm -rf ${DBIR}
    
    Login or Signup to reply.
  6. <?php
    
    $BASH_Command='curl -s -X POST "https://api.telegram.org/bot<YourToken>/sendPhoto?chat_id=<YourID>" -F photo="@/path/to/imagefile.jpeg" -F caption="TheImage" > /dev/null &';
    
    echo exec($BASH_Command);
    ?>
    
    Login or Signup to reply.
  7. I thought I should extend the answer to include uploading from an external url but it still involves a process of saving the image to a folder first. Then I added a caption to the image.

        $bot_url    = "https://api.telegram.org/bot<bot_id>/";
        $url        = $bot_url . "sendPhoto?chat_id=" . $chat_id ;
        $caption = 'Telegram Image SendPhoto function';
        $img = '/path/to/save_image.png'; //local path where image should be saved
    
        /* Get the image from the URL and save to your own path. You need to add 
        allow_url_fopen=On to your php.ini file for the below code to work */
    
        file_put_contents($img, file_get_contents("https://your_image.com/pic.jpg")); 
        $post_fields = array('chat_id'   => $chat_id,
        'photo'     => new CURLFile(realpath($img)),
        'caption' => $caption
        );
    
        $ch = curl_init(); 
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
       "Content-Type:multipart/form-data"
        ));
        curl_setopt($ch, CURLOPT_URL, $url); 
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields); 
        $output = curl_exec($ch);
        curl_close($ch); //close curl
    

    That’s all!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search