【问题标题】:Telegram BOT Api: how to send a photo using PHP?Telegram BOT Api:如何使用 PHP 发送照片?
【发布时间】:2015-11-24 14:29:55
【问题描述】:

sendPhoto 命令需要一个参数photo,定义为InputFile or String

API 文档告诉:

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.

还有

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. 

所以我尝试了这个方法

    $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);

卷曲已执行,但 Telegram 回复我:

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

我也尝试用file_get_contents 替换@/path...,但在这种情况下,Telegram 给我一个空回复(而curl_error 是空的!)。

使用 php + curl 将照片发送到电报的方式是什么?

【问题讨论】:

    标签: php curl telegram telegram-bot


    【解决方案1】:

    这是我的工作解决方案,但它需要 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);
    

    【讨论】:

    • @realtebo 我去掉了绒毛。如果您认为我的编辑不相关,请回滚。
    • 嘿!完美运行。快速提问:除了你自己的服务器,有没有办法从 URL 发送图片?
    • 我在将文件发送到聊天 ID 包含 @ 的频道时遇到问题,因此 PHP 5.5 之前的 CURL 使用 @ 来识别文件输入。经过研究,我找到了向 curl 添加以下选项的解决方案:curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true); 并且它的工作完美。感谢@realtebo 的回答。
    • 有人试过在上面添加标题和回复标记吗?我不能让它工作。
    • 您好,可以发送带有图片的消息的文本吗?我想发送带有文本的 gif ......或者更好:带有 gif 附件的文本
    【解决方案2】:

    这段代码对我有很大帮助,我从这里的 php.net 网站获得

    访问http://php.net/manual/en/class.curlfile.php#115161 (在 php 网站上投票支持此代码).

    我只是更改此代码中的标题,以便电报机器人发送图像只需复制此功能

    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
                  ),
              ));
          }
    

    基本尝试:现在只需通过发送带有路径和聊天 ID 的照片名称来使用此代码 方法如下:-

    $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);
    

    对于发送 png 或其他方法,请根据需要更改 curl_custom 函数。

    【讨论】:

      【解决方案3】:

      我在网上搜索了很多,但没有找到答案。但是,你的问题解决了我的问题......我只是改变了你的代码,并为我回答了它...... 我将您的代码更改为:

      $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;
      

      【讨论】:

        【解决方案4】:

        您可以使用此 API:https://github.com/mgp25/Telegram-Bot-API

        示例:

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

        您可以使用存储的图像或 URL。

        【讨论】:

        • 嗨,为什么当我使用该代码时会显示如下通知:file_get_contents(api.telegram.org/bot266009680:AAEvufrOSAdLIxoXKtfgcfgfc/…): failed to open stream: HTTP request failed!第 466 行 C:\xampp\htdocs\mgp25\Telegram-Bot-API-master\src\Telegram.php 中的 HTTP/1.1 400 错误请求
        【解决方案5】:
        <?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);
        ?>
        

        【讨论】:

          【解决方案6】:

          这是个坏主意,但您可以使用类似的方法:

          #!/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}
          

          【讨论】:

            【解决方案7】:

            我认为我应该扩展答案以包括从外部 url 上传,但它仍然涉及首先将图像保存到文件夹的过程。然后我为图片添加了标题。

                $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
            

            就是这样!

            【讨论】:

              猜你喜欢
              • 2016-07-09
              • 1970-01-01
              • 2018-11-12
              • 2015-09-20
              • 1970-01-01
              • 2017-06-06
              • 2021-10-03
              • 2021-04-24
              • 2016-03-16
              相关资源
              最近更新 更多