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 ?
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);
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.
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;
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.
<?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);
?>
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}
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!
Related
I get JSON from the Soundcloud API by using code in section【A】.
But I want to get it without using $type, like in code【B】.
In other words, I want to get that information by only giving $target.
What should I do?
$r = soundcloud_responce();
var_dump( $r );
function soundcloud_responce(){
$client_id = 'xxx';
$type = 'tracks';
$q = 'words';
// code【A】
// If I have $type, So this process ok.
$url = "https://api.soundcloud.com/";
$url .= $type;
$url .= "?client_id=$client_id";
$url .= "&q=$q";
// code【B】
// I want to do same process with $target but without $type
$target = "https://soundcloud.com/accountname/trackname";
$target = str_replace('https://soundcloud.com/', '', $target);
$url = "https://api.soundcloud.com/";
$url .= $target;
$url .= "?client_id=$client_id";
// curl
$ch = curl_init();
$headers = [
'Accept: application/json',
'Content-Type: application/json',
];
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$res = curl_exec($ch);
$json = json_decode($res);
curl_close($ch);
return $json;
}
(Add 2020-02-21-09:38 #Tokyo)
I tried this code【C】but this also failed.
// code【C】
// I tried with oembed but this also failed.
$target = "https://soundcloud.com/accountname/trackname";
$url = 'http://soundcloud.com/oembed?format=json&url='.$target;
(Add 2020-02-21-10:12 #Tokyo)
I tried this code【D】but this also failed.
// code【D】
// I tried with resolve but this also failed.
$target = "https://soundcloud.com/accountname/trackname";
$url = "https://api.soundcloud.com/resolve?url=$target&client_id=$client_id";
I tried this code【E】this is successful!
Thank you for giving me good advice, #showdev.
// code【E】
// this is successful!
$target = "https://soundcloud.com/accountname/trackname";
$target = urlencode($target);
$url = "https://api.soundcloud.com/resolve.json?url=$target&client_id=$client_id";
in function input $files = $_FILES
Don't get what Telegram wants from me.
It says: "{"ok":false,"error_code":400,"description":"Bad Request: group send failed"}". HIELPLEAS!
function sendMediaGroup($files)
{
$url = "https://api.telegram.org/bot" . $this->token . "/" . __FUNCTION__;
$media = [];
$ch = curl_init();
$type = "photo";
$caption = "";
foreach ($files as $file)
{
$media[] = [
'type' => $type,
'media' => $file['tmp_name'],
'caption' => $caption
];
}
$disable_notification = false;
$reply_to_message_id = null;
$parameters = [
'chat_id' => $this->chat_id,
'media' => json_encode($media),
'disable_notification' => $disable_notification,
'reply_to_message_id' => $reply_to_message_id,
];
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, $parameters);
return $output = curl_exec($ch);
}
In order for Telegram to create a media group from photo URL in the Internet, a file link you pass as media attribute value must be accessible by Telegram's servers. Sometimes it is not the case and sendMediaGroup API call fails with the cryptic error message Bad Request: group send failed. In this case you can try another approach to send photos, e.g. in text field using sendMessage method or go to #webpagebot and send him a link to your file - this will update preview for the link and you will be able to send that link inside of the media group.
Note to moderators: this answer does not 100% targets original question, but link to this question pops up in first ten while searching using words from the caption.
You should name your files and attach files to the request according their name. So change your code like this:
function sendMediaGroup($files)
{
$url = "https://api.telegram.org/bot" . $this->token . "/" . __FUNCTION__;
$media = [];
$ch = curl_init();
$type = "photo";
$caption = "";
$parameters = array();
foreach ($files as $file)
{
$media[] = [
'type' => $type,
'media' => "attach://" . $file['tmp_name'],
'caption' => $caption
];
$parameters[] = [
$file['tmp_name'] => $file
];
}
$disable_notification = false;
$reply_to_message_id = null;
$parameters[] = [
'chat_id' => $this->chat_id,
'media' => json_encode($media),
'disable_notification' => $disable_notification,
'reply_to_message_id' => $reply_to_message_id,
];
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, $parameters);
return $output = curl_exec($ch);
}
If you are setting URL for media, you URL should work on :80 or :443 port. For example: https:examplesite.com/image1.jpg is OK, https:examplesite.com:8443/image1.jpg is not OK!
I'm using PHP to config a webhook for a BOT.
I'd like to send picture from another server.
I've tried this way
function bot1($chatID,$sentText) {
$botUrl = 'https://api.telegram.org/bot'.self::_BOT_TOKEN_;
$img = "https://www.server2.com/1.jpeg";
$this->sendPhoto($botUrl,$chatID,$img);
}
function sendPhoto($botUrl,$chatID, $img){
$this->sendMessage($botUrl,$chatID,'This is the pic'.$chatID);
$this->sendPost($botUrl,"sendPhoto",$chatID,"photo",$img);
}
function sendMessage($botUrl,$chatID, $text){
$inserimento = file_get_contents($botUrl."/sendMessage?chat_id=".$chatID."&text=".$text."&reply_markup=".json_encode(array("hide_keyboard"=>true)));
}
function sendPost($botUrl,$function,$chatID,$type,$doc){
$response = $botUrl. "/".$function;
$post_fields = array('chat_id' => $chatID,
$type => new CURLFile(realpath($doc))
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type:multipart/form-data"
));
curl_setopt($ch, CURLOPT_URL, $response);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
$output = curl_exec($ch);
}
But I receive only the message.
What is the problem?
I've tried to change in http but the problem persists
Well, I've done a workaround because my cUrl version seems to have a bug in uploading file.
Now I use Zend FW
$botUrl = 'https://api.telegram.org/bot'.self::_BOT_TOKEN_;
$realpath = realpath($doc);
$url = $botUrl . "/sendPhoto?chat_id=" . $chatID;
$client = new Zend_Http_Client();
$client->setUri($url);
$client->setFileUpload($realpath, "photo");
$client->setMethod('POST');
$response = $client->request();
You have to send a file, not a URL.
So:
function bot1( $chatID,$sentText )
{
$botUrl = 'https://api.telegram.org/bot'.self::_BOT_TOKEN_;
$img = "https://www.server2.com/1.jpeg";
$data = file_get_contents( $img ); # <---
$filePath = "/Your/Local/FilePath/Here"; # <---
file_put_contents( $data, $filePath ); # <---
$this->sendPhoto( $botUrl, $chatID, $filePath ); # <---
}
This is as raw example, without checking success of file_get_contents().
In my bot I use this schema, and it works fine.
I need to convert this command line cURL into a php cURL and echo the result
curl -H "Content-Type: application/json" -d '{ "code":"<code>", "client_id": "<client_id>", "client_secret": "<client_secret>"}' https://www.example.com/oauth/access_token
how can this be done?
Try this simple approach:
$data = array("code"=>"123", "client_id"=> "123", "client_secret"=> "123");
$data_string = json_encode($data);
$ch = curl_init('https://www.example.com/oauth/access_token');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
Replace 123 with your values. Here is the manual for curl_setopt()
Something like this should work, assuming you need to POST the data to the URL:
<?php
// URL that the data will be POSTed to
$curl_url = 'https://www.example.com/oauth/access_token';
// Convert the data into an array
$curl_data_arr = array('{ "code":"<code>", "client_id": "<client_id>", "client_secret": "<client_secret>"}');
// Prepare to post as an array
$curl_post_fields = array();
foreach ($curl_data_arr as $key => $value) {
// Assuming you need the values url encoded, this is an easy way
$curl_post_fields[] = $key . '=' . urlencode($value);
}
$curl_header = array('Content-Type: application/json');
$curl_array = array(
CURLOPT_URL => $curl_url,
CURLOPT_HTTPHEADER => $curl_header,
CURLOPT_POSTFIELDS => implode('&', $curl_post_fields),
CURLOPT_POST => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
);
// Initialize cURL
$curl = curl_init();
// Tell cURL to use the array of options we just set up
curl_setopt_array($curl, $curl_array);
// Assign the result to $data
$data = curl_exec($curl);
// Empty variable (at first) to avoid errors being displayed
$result = '';
// Check for errors
if ($error = curl_error($curl)) {
// If there's an error, assign its value to $result
$result = $error;
}
curl_close($curl);
// If there's no errors...
if (empty($error)) {
// ... instead assign the value of $data to $result
$result = $data;
}
echo $result;
I need to HTTP PUT a csv file and some POST fields using multipart POST with PHP and Curl to a REST API endpoint.
The contents of the file upload is stored in a variable $list. The other end point is $url.
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_PUT, true);
$post = array(
//Other Post fields array
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$fh = fopen('php://memory', 'rw');
fwrite($fh, $list);
rewind($fh);
curl_setopt($ch, CURLOPT_INFILE, $fh);
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($list));
$response = curl_exec($ch);
The above code seems to work the only problem is that the other end point requires a specific fieldname for the file upload. How do i set a filename ?
Am i doing something wrong ?
This is the PUT format they have mentioned on API
Content-Disposition: form-data; name="list[csv]"; filename="RackMultipart20110923-63966-hfpyg"
Content-Length: 33
Content-Type: text/csv
Content-Transfer-Encoding: binary
xxxx
yyyy
zzzz
-------------MultipartPost
Content-Disposition: form-data; name="list[list_type]"
Blacklist
-------------MultipartPost--
FYI that is multipart/form-data. You will need to build the body yourself I think, I don't think cURL could be made to build that sort of request with a PUT request. However, this is not a serious problem:
<?php
function recursive_array_mpfd ($array, $separator, &$output, $prefix = '') {
// Recurses through a multidimensional array and populates $output with a
// multipart/form-data string representing the data
foreach ($array as $key => $val) {
$name = ($prefix) ? $prefix."[".$key."]" : $key;
if (is_array($val)) {
recursive_array_mpfd($val, $separator, $output, $name);
} else {
$output .= "--$separator\r\n"
. "Content-Disposition: form-data; name=\"$name\"\r\n"
. "\r\n"
. "$val\r\n";
}
}
}
// This will hold the request body string
$requestBody = '';
// We'll need a separator
$separator = '-----'.md5(microtime()).'-----';
// First add the postfields
$post = array(
//Other Post fields array
);
recursive_array_mpfd($post, $separator, $requestBody);
// Now add the file
$list = "this,is,some,csv,data"; // The content of the file
$filename = "data.csv"; // The name of the file
$requestBody .= "--$separator\r\n"
. "Content-Disposition: form-data; name=\"list[list_type]\"; filename=\"$filename\"\r\n"
. "Content-Length: ".strlen($list)."\r\n"
. "Content-Type: text/csv\r\n"
. "Content-Transfer-Encoding: binary\r\n"
. "\r\n"
. "$list\r\n";
// Terminate the body
$requestBody .= "--$separator--";
// Let's go cURLing...
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: multipart/form-data; boundary="'.$separator.'"'
));
$response = curl_exec($ch);
If you have any problems with this, try echo $requestBody; before the cURL request and make sure it looks like you expect it to.