Telegram BOT Api: how to send a photo using PHP?
Asked Answered
C

7

10

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 ?

Capacitate answered 30/8, 2015 at 11:53 Comment(0)
C
39

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);
Capacitate answered 30/8, 2015 at 12:3 Comment(5)
@Capacitate I removed fluff. Rollback if you think my edit isn't relevant.Substantialize
Hey! Works perfectly. Quick question: is there a way to send a picture from a URL aside from your own server?Mallee
I had problem with sending file to channel where chat id contains @ hence CURL before PHP 5.5 use @ to identify fileinput. After research I found solution with add following option to curl: curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true); and its work perfectly. thanks @Capacitate for your answer.Chelton
anyone tried adding caption and reply_markup on this? I can't make it work.Megalomania
Hi, it is possible to send also text with a message with a image? I'd like to send a gif with text....or better: text with gif attachmentMarmoset
F
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("\0", "\"", "\r", "\n");

          // build normal parameters
          foreach ($assoc as $k => $v) {
              $k = str_replace($disallow, "_", $k);
              $body[] = implode("\r\n", 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("\r\n", 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}\r\n{$part}";
          });

          // add final boundary
          $body[] = "--{$boundary}--";
          $body[] = "";

          // set options
          return @curl_setopt_array($ch, array(
              CURLOPT_POST       => true,
              CURLOPT_POSTFIELDS => implode("\r\n", $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.

Fickle answered 29/9, 2015 at 12:34 Comment(0)
M
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;
Microseism answered 8/9, 2015 at 12:0 Comment(0)
B
1

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.

Birkenhead answered 6/9, 2015 at 9:22 Comment(1)
hi, why when i used that code is show notice like this : file_get_contents(api.telegram.org/bot266009680:AAEvufrOSAdLIxoXKtfgcfgfc/…): failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request in C:\xampp\htdocs\mgp25\Telegram-Bot-API-master\src\Telegram.php on line 466Waldemar
I
1
<?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);
?>
Impetuosity answered 15/6, 2018 at 23:47 Comment(0)
B
0

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}
Bunyip answered 27/11, 2017 at 19:36 Comment(0)
V
0

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!

Vickievicksburg answered 16/8, 2021 at 23:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.