php-telegram-bot / core

PHP Telegram Bot based on the official Telegram Bot API
MIT License
3.87k stars 951 forks source link

Launch other command on inline keyboard button click #251

Closed sigaev-pro closed 8 years ago

sigaev-pro commented 8 years ago

First of all thanks for great job!

I have created callbackquery command where I'm checking the callback_data for a string like "order:123". I need to start an other command such as /reply 123. But when I'm trying

return $this->telegram->executeCommand('reply 123');

I'm getting following exception:

PHP message: PHP Fatal error:  Uncaught Error: Call to a member function getChat() on nul
l in /home/cargo/larabot/vendor/longman/telegram-bot/src/Commands/SystemCommands/GenericCommand.php:37
Stack trace:
#0 /home/cargo/larabot/vendor/longman/telegram-bot/src/Commands/Command.php(131): Longman\TelegramBot\Commands\SystemCommands\GenericCommand->execute()
#1 /home/cargo/larabot/vendor/longman/telegram-bot/src/Telegram.php(437): Longman\TelegramBot\Commands\Command->preExecute()
#2 /home/cargo/larabot/vendor/longman/telegram-bot/src/Telegram.php(428): Longman\TelegramBot\Telegram->executeCommand('Generic')
#3 /home/cargo/larabot/commands/CallbackqueryCommand.php(53): Longman\TelegramBot\Telegram->executeCommand('oreply 18')
#4 /home/cargo/larabot/vendor/longman/telegram-bot/src/Commands/Command.php(131): Longman\TelegramBot\Commands\SystemCommands\CallbackqueryCommand->execute()
#5 /home/cargo/larabot/vendor/longman/telegram-bot/src/Telegram.php(437): Longman\TelegramBot\Commands\Command->preExecute()

Does it a way to do it?

noplanman commented 8 years ago

At the moment there is no clean way to execute a subcommand. Seems like one of those obvious things that one should just be able to do, right? The only thing that I can think of, is to extract the functionality from the /reply command you're trying to call and execute it specifically.

If you need a more thorough explanation, let me know!

@akalongman @MBoretto @jacklul Am I just totally oblivious to the library actually being able to do this? The only way I found of doing this is the following, which is an ugly hack and I'm not exactly sure of all the things it might break:

// In the command's execute(), if we want to send "/echo testing".
// Note that we explicitly need to create the EchoCommand object!
$ud = clone $this->getUpdate();
\Tests\TestHelpers::setObjectProperty($ud->getMessage(), 'text', '/echo testing');
(new EchoCommand($this->telegram, $ud))->preExecute();
jacklul commented 8 years ago

You can instead be sending /replyparameter command and then explode "" and execute first part then inside reply command extract the second part and use it as a parameter, thats how i did contact/reply system in my bots.

So I have a contact command that puts inline button under user message:

'text' => "Reply",
'callback_data' => 'reply_' . $message->getFrom()->getId()

then in callbackquerycommand I have this simple thing:

$data = $callback_query->getData();
$command = explode('_', $data);
$command = $command[0];

if ($this->getTelegram()->getCommandObject($command)) {
            return $this->getTelegram()->executeCommand($command);
}

and then on top of my reply command i have:

$testtext = explode('reply_', $command);
$text = $testtext[1];

hope this helps