Closed progS1m closed 8 years ago
The uploaded files aren't saved anywhere automatically at the moment...
What you could do in the meantime, is create a custom command, say /upload
, and then save the uploaded file then.
I'll put together the command for you to use, stay tuned!
If you feel like exploring a bit in the meantime, take a look at the SurveyCommand.php
file and look here how to save an uploaded file:
https://github.com/akalongman/php-telegram-bot/issues/123#issuecomment-224523310
@MBoretto @jacklul @akalongman Should every file that gets uploaded to the bot automatically be saved to the Upload folder? Would make sense, right?
At the moment the Upload folder isn't even used!
Not by default. I noticed on my bot there is a lot of people who just try to send files to the bot, most likely viruses and stuff.
Mhm it shouldn't be activated by default. My bot I develop is for a game (mrX). Only user with a specific /join 'token' can join respectively will be able to use all commands. For some challenges in the game they need to upload pictures, which an admin later analyse manually and if challenge passed they get credits.
@jacklul You're absolutely right, by default isn't a good idea. We could add a setting for those people who would want that, or at least a helper to make file downloads less painful.
@xtrahost Voilà, save as UploadCommand.php
in your custom commands folder. Being a UserCommand
, anyone can use it! So you might want to change it to an AdminCommand
.
<?php
/**
* This file is part of the TelegramBot package.
*
* (c) Avtandil Kikabidze aka LONGMAN <akalongman@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Longman\TelegramBot\Commands\UserCommands;
use Longman\TelegramBot\Request;
use Longman\TelegramBot\Conversation;
use Longman\TelegramBot\Commands\UserCommand;
use Longman\TelegramBot\Entities\ForceReply;
use Longman\TelegramBot\Entities\ReplyKeyboardHide;
use Longman\TelegramBot\TelegramLog;
/**
* User "/upload" command
*/
class UploadCommand extends UserCommand
{
/**#@+
* {@inheritdoc}
*/
protected $name = 'upload';
protected $description = 'Upload and save files';
protected $usage = '/upload';
protected $version = '0.0.1';
protected $need_mysql = true;
/**#@-*/
/**
* Conversation Object
*
* @var Longman\TelegramBot\Conversation
*/
protected $conversation;
/**
* {@inheritdoc}
*/
public function execute()
{
$message = $this->getMessage();
$chat = $message->getChat();
$user = $message->getFrom();
$chat_id = $chat->getId();
$user_id = $user->getId();
//Preparing Response
$data = [
'chat_id' => $chat_id,
'reply_markup' => new ReplyKeyBoardHide(['selective' => true]),
];
if ($chat->isGroupChat() || $chat->isSuperGroup()) {
//reply to message id is applied by default
$data['reply_to_message_id'] = $message->getMessageId();
//Force reply is applied by default to so can work with privacy on
$data['reply_markup'] = new ForceReply([ 'selective' => true]);
}
//Conversation start
$this->conversation = new Conversation($user_id, $chat_id, $this->getName());
if (in_array($message->getType(), ['audio', 'document', 'photo', 'video', 'voice'])) {
$doc = call_user_method('get' . $message->getType(), $message);
($message->getType() === 'photo') && $doc = $doc[0];
$file_id = $doc->getFileId();
$file = Request::getFile(['file_id' => $file_id]);
if ($file->isOk() && Request::downloadFile($file->getResult())) {
$data['text'] = $message->getType() . ' file is located at: ' . $this->telegram->getDownloadPath() . '/' . $file->getResult()->getFilePath();
} else {
$data['text'] = 'Failed to download.';
}
$this->conversation->notes['file_id'] = $file_id;
$this->conversation->update();
$this->conversation->stop();
} else {
$data['text'] = 'Please upload the file now';
}
return Request::sendMessage($data);
}
}
Thanks a lot @noplanman works fine. Except that it will store only the smallest photo version.
Right, my bad, sorry. The line in question is this one:
($message->getType() === 'Photo') && $doc = $doc[0];
Replace it with this one for the highest resolution:
($message->getType() === 'Photo') && $doc = end($doc);
Just amazing! Thank you, in my view we can close the issue.
Ok 👍
We'll be working on a better implementation of this, but until then you can use the /upload
command as a workaround.
hi guys! thank you noplanman for answering this issue! but i got some error on your code. I've tried to fix it but I was not successful! these are what I got in error log: [21-Dec-2016 20:46:52 UTC] PHP Deprecated: Function call_user_method() is deprecated in /home/mybotpro/public_html/Project/vendor/longman/telegram-bot/src/Commands/UserCommands/SendImgCommand.php on line 82 [21-Dec-2016 20:46:52 UTC] PHP Fatal error: Call to a member function getFileId() on array in /home/mybotpro/public_html/Project/vendor/longman/telegram-bot/src/Commands/UserCommands/SendImgCommand.php on line 85
what can I do to fix this?
Could you post the code of your SendImgCommand.php
please?
<?php
/**
* This file is part of the TelegramBot package.
*
* (c) Avtandil Kikabidze aka LONGMAN <akalongman@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Longman\TelegramBot\Commands\UserCommands;
use Longman\TelegramBot\Request;
use Longman\TelegramBot\Conversation;
use Longman\TelegramBot\Commands\UserCommand;
use Longman\TelegramBot\Entities\ForceReply;
use Longman\TelegramBot\Entities\ReplyKeyboardHide;
use Longman\TelegramBot\TelegramLog;
/**
* User "/cancel" command
*
* This command cancels the currently active conversation and
* returns a message to let the user know which conversation it was.
* If no conversation is active, the returned message says so.
*/
class SendImgCommand extends UserCommand
{
/**
* @var string
*/
protected $name = 'sendimg';
/**
* @var string
*/
protected $description = 'ارسال عکس';
/**
* @var string
*/
protected $usage = '/sendimg';
/**
* @var string
*/
protected $version = '0.2.0';
protected $conversation;
/**
* {@inheritdoc}
*/
public function execute()
{
$servername = "mybotprovider.ir";
$username = "mybotpro_admin";
$password = "1a2a3a4197";
$dbname = "mybotpro_telegram";
$mysql_credentials = [
'host' => $servername,
'user' => $username,
'password' => $password,
'database' => $dbname,
];
$this->telegram->enableMySQL($mysql_credentials);
$message = $this->getMessage();
$chat_id = $message->getChat()->getId();
$from = $message->getFrom();
$user_name = $from->getUsername();
$user_id = $from->getId();
//Preparing Response
$data = [
'chat_id' => $chat_id,
];
$doc = call_user_method('get' . $message->getType(), $message);
($message->getType() === 'Photo') && $doc = $doc[0];
$file_id = $doc->getFileId();
$file = Request::getFile(['file_id' => $file_id]);
if ($file->isOk() && Request::downloadFile($file->getResult())) {
$data['text'] = $message->getType() . ' file is located at: ' . $this->telegram->getDownloadPath() . '/' . $file->getResult()->getFilePath();
} else {
$data['text'] = 'Failed to download.';
}
return Request::sendMessage($data);
}
}
also i got this error when i was trying to connect to mysql for creating a conversation.
[21-Dec-2016 20:36:52 UTC] PHP Warning: date(): It is not safe to rely on the system's timezone settings. You are required to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/mybotpro/public_html/Project/vendor/longman/telegram-bot/src/DB.php on line 245
[21-Dec-2016 20:36:52 UTC] PHP Warning: PDOStatement::execute(): SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (mybotpro_telegram
.conversation
, CONSTRAINT conversation_ibfk_1
FOREIGN KEY (user_id
) REFERENCES user
(id
)) in /home/mybotpro/public_html/Project/vendor/longman/telegram-bot/src/ConversationDB.php on line 107
I got the second error in this code:
<?php
/**
* This file is part of the TelegramBot package.
*
* (c) Avtandil Kikabidze aka LONGMAN <akalongman@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Longman\TelegramBot\Commands\UserCommands;
use Longman\TelegramBot\Commands\UserCommand;
use Longman\TelegramBot\Conversation;
use Longman\TelegramBot\Entities\Keyboard;
use Longman\TelegramBot\Request;
use Longman\TelegramBot\Telegram;
/**
* User "/cancel" command
*
* This command cancels the currently active conversation and
* returns a message to let the user know which conversation it was.
* If no conversation is active, the returned message says so.
*/
class SendImgCommand extends UserCommand
{
/**
* @var string
*/
protected $name = 'sendimg';
/**
* @var string
*/
protected $description = 'ارسال عکس';
/**
* @var string
*/
protected $usage = '/sendimg';
/**
* @var string
*/
protected $version = '0.2.0';
protected $conversation;
/**
* {@inheritdoc}
*/
public function execute()
{
$servername = "mybotprovider.ir";
$username = "mybotpro_admin";
$password = "1a2a3a4197";
$dbname = "mybotpro_telegram";
$mysql_credentials = [
'host' => $servername,
'user' => $username,
'password' => $password,
'database' => $dbname,
];
$telegram->enableMySQL($mysql_credentials);
$message = $this->getMessage();
$chat = $message->getChat();
$user = $message->getFrom();
$chat_id = $chat->getId();
$user_id = $user->getId();
//Preparing Response
$data = [
'chat_id' => $chat_id,
];
//Conversation start
$this->conversation = new Conversation($user_id, $chat_id, $this->getName());
if (in_array($message->getType(), ['Audio', 'Document', 'Photo', 'Video', 'Voice'])) {
$doc = call_user_method('get' . $message->getType(), $message);
($message->getType() === 'Photo') && $doc = $doc[0];
$file_id = $doc->getFileId();
$file = Request::getFile(['file_id' => $file_id]);
if ($file->isOk() && Request::downloadFile($file->getResult())) {
$data['text'] = $message->getType() . ' file is located at: ' . $this->telegram->getDownloadPath() . '/' . $file->getResult()->getFilePath();
} else {
$data['text'] = 'Failed to download.';
}
$this->conversation->notes['file_id'] = $file_id;
$this->conversation->update();
$this->conversation->stop();
} else {
$data['text'] = 'Please upload the file now';
}
return Request::sendMessage($data);
}
}
hey noplanman! thanks a lot for your response.
I'm waiting for your answer. as you know, there aren't many sources about creating telegram bot on php. so I'm really looking forward to hearing an answer from you.
my main problems are:
I'm waiting ... so please don't let me down.
First of all, the MySQL connection info shouldn't be here, it should be in your hook.php
.
Also, the getType
method returns a lowercase string since version 0.36 (I think).
Some lines need to be changed, namely:
...
if (in_array($message->getType(), ['audio', 'document', 'photo', 'video', 'voice'], true)) {
$doc = call_user_func([$message, 'get' . ucfirst($message->getType())]);
($message->getType() === 'photo') && $doc = $doc[0];
...
Does that help enough?
thank you so mush noplanman! you actually have saved my life !!! now i can get filepath without any problem.
but about mysql connection i also have some problems.
I set mysql connection method inside hook.php and then unset webhook and reset it. but when i put this line:
protected $need_mysql = true;
inside SendImgCommand.php and run it, I get this message in my bot:
Sorry no database connection, unable to execute "sendimg" command.
this is my hook.php:
<?php
// Load composer
require __DIR__ . '/vendor/autoload.php';
$API_KEY = 'api-key';
$BOT_NAME = 'bot-name';
try {
// Create Telegram API object
$telegram = new Longman\TelegramBot\Telegram($API_KEY, $BOT_NAME);
// Handle telegram webhook request
$telegram->handle();
$mysql_credentials = [
'host' => 'mybotprovider.ir',
'user' => 'mybotpro_admin',
'password' => '1a2a3a4197',
'database' => 'mybotpro_telegram',
];
$telegram->enableMySQL($mysql_credentials);
} catch (Longman\TelegramBot\Exception\TelegramException $e) {
// Silence is golden!
// log telegram errors
// echo $e;
}
?>
So what do you think about it? what is the problem?
You need to enable MySQL before handling the request! 😉
(on a side note, when you post code, use the triple backticks with PHP syntax highlighting. Edit your comment above to see what I mean and read more about it here)
you did the best for me, but I can't do anything for you except being Grateful and have best wishes for you! thanks you a lot!
You're so welcome 😊 Happy to hear it's working now.
I've a problem that I can't see any files, photos, etc sent from my mobile phone.
To figure out where the files should be located I used this code in hook.php
echo $telegram->getUploadPath();
Output from Browser: /var/www/website.tld/mybot/php-telegram-bot/src/../Upload
So the location for uploaded files should be there /var/www/website.tld/mybot/php-telegram-bot/src/Upload right?
All the folder permissions should be correct. Webserver (Nginx) runs as www-data.
In my update.log I can see that a new entry is getting generated when sending a file from mobile phone. Per example audio looks like this:
{"update_id":86454387, "message":{"message_id":601,"from":{"id":123456789,"first_name":"myFirstname","last_name":"myLastName"},"chat":{"id":123456789,"first_name":"myFirstname","last_name":"myLastName","type":"private"},"date":1465411058,"voice":{"duration":1,"mime_type":"audio\/ogg","file_id":"AwADBAADBQAD3QozDt94YZV9NlHoAg","file_size":2750}}}
When I try to debug with the setCustomInput function and call the hook.php via browser I don't get an error.
No related log entry in debug.log or error.log is visible.
Has someone an idea what could cause this issue? Thanks for help!
PHP Version: PHP 5.6.20-0+deb8u1 (cli) (built: Apr 27 2016 11:26:05) Copyright (c) 1997-2016 The PHP Group Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
php-telegram-bot version: 0.33