Core: Unable to start a command from CallbackQuery

Created on 18 Jan 2018  路  3Comments  路  Source: php-telegram-bot/core

Required Information

  • Operating system: RASPBIAN STRETCH LITE
  • PHP version: 7.0.19-1 (32bit); apache2handler; Linux
  • PHP Telegram Bot version: 0.52.0
  • Using MySQL database: no
  • Update Method: Webhook
  • Self-signed certificate: yes
  • RAW update (if available):

Expected behaviour


From callback, call a custom command e print a simple "Simple text" on chat

Actual behaviour


No error in php but nothing showing in chat

I'm using inline keyboard with callback, command is "start": ( it works)

<?php
/**
 * This file is part of the TelegramBot package.
 *
 * (c) Avtandil Kikabidze aka LONGMAN <[email protected]>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Longman\TelegramBot\Commands\SystemCommands;

use Longman\TelegramBot\Commands\SystemCommand;
use Longman\TelegramBot\Entities\InlineKeyboard;
use Longman\TelegramBot\Request;

/**
 * User "/inlinekeyboard" command
 *
 * Display an inline keyboard with a few buttons.
 */
class StartCommand extends SystemCommand
{
    /**
     * @var string
     */
    protected $name = 'start';

    /**
     * @var string
     */
    protected $description = 'Elenca i comandi disponibili';

    /**
     * @var string
     */
    protected $usage = '/start';

    /**
     * @var string
     */
    protected $version = '1.0.0';

    /**
     * Command execute method
     *
     * @return \Longman\TelegramBot\Entities\ServerResponse
     * @throws \Longman\TelegramBot\Exception\TelegramException
     */
    public function execute()
    {
        $chat_id = $this->getMessage()->getChat()->getId();

        $text = 'Benvenuto!'.PHP_EOL;
        $text.= 'Questi sono i comandi che puoi usare:'.PHP_EOL;

        $switch_element = mt_rand(0, 9) < 5 ? 'true' : 'false';

        /*$inline_keyboard = new InlineKeyboard([
            ['text' => 'inline', 'switch_inline_query' => $switch_element],
            ['text' => 'inline current chat', 'switch_inline_query_current_chat' => $switch_element],
        ], [
            ['text' => 'callback', 'callback_data' => 'identifier'],
            ['text' => 'open url', 'url' => 'https://github.com/php-telegram-bot/core'],
        ]);*/

        /*$inline_keyboard = new InlineKeyboard([
            ['text' => 'Sensori', 'switch_inline_query' => 'getSensorList']
        ]);*/

        $inline_keyboard = new InlineKeyboard([

            ['text' => 'Sensori' , 'callback_data' => 'sensori'],
            ['text' => 'Luci' , 'callback_data' => 'luci']

        ]);

        $data = [
            'chat_id'      => $chat_id,
            'text'         => $text,
            'reply_markup' => $inline_keyboard,
            'parse_mode' => 'markdown',
        ];

        return Request::sendMessage($data);
    }
}

I receive the callback into CallbackqueryCommand.php: (it works.... but nothing is printed on chat)

<?php
/**
 * This file is part of the TelegramBot package.
 *
 * (c) Avtandil Kikabidze aka LONGMAN <[email protected]>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Longman\TelegramBot\Commands\SystemCommands;

use Longman\TelegramBot\Commands\SystemCommand;
use Longman\TelegramBot\Request;

/**
 * Callback query command
 */
class CallbackqueryCommand extends SystemCommand
{
    /**
     * @var callable[]
     */
    protected static $callbacks = [];

    /**
     * @var string
     */
    protected $name = 'callbackquery';

    /**
     * @var string
     */
    protected $description = 'Reply to callback query';

    /**
     * @var string
     */
    protected $version = '1.0.0';

    /**
     * Command execute method
     *
     * @return mixed
     * @throws \Longman\TelegramBot\Exception\TelegramException
     */
    /*public function execute()
    {
        //$callback_query = $this->getUpdate()->getCallbackQuery();
        //$user_id        = $callback_query->getFrom()->getId();
        //$query_id       = $callback_query->getId();
        //$query_data     = $callback_query->getData();

        // Call all registered callbacks.
        foreach (self::$callbacks as $callback) {
            $callback($this->getUpdate()->getCallbackQuery());
        }

        return Request::answerCallbackQuery(['callback_query_id' => $this->getUpdate()->getCallbackQuery()->getId()]);
    }*/

    public function execute()
    {


        $callback_query    = $this->getCallbackQuery();
        $callback_query_id = $callback_query->getId();
        $callback_data     = $callback_query->getData();



        return Request::editMessageText([
            'chat_id'    => $callback_query->getMessage()->getChat()->getId(),
            'message_id' => $callback_query->getMessage()->getMessageId(),
            'text'       => \Longman\TelegramBot\Commands\UserCommands\SimpleCommand::$dummy
        ]);
    }

    /**
     * Add a new callback handler for callback queries.
     *
     * @param $callback
     */
    public static function addCallbackHandler($callback)
    {
        self::$callbacks[] = $callback;
    }
}

This is the SimpleCommand (alone it works)

<?php

namespace Longman\TelegramBot\Commands\UserCommands;

use Longman\TelegramBot\Commands\UserCommand;
use Longman\TelegramBot\Request;

class SimpleCommand extends UserCommand
{
    protected $name = 'simple';                      // Your command's name
    protected $description = 'A command for test'; // Your command description
    protected $usage = '/simple';                    // Usage of your command
    protected $version = '1.0.0';                  // Version of your command

    public static $dummy = '';

    // nothing


    public function execute()
    {
        $message = $this->getMessage();            // Get Message object

        $chat_id = $message->getChat()->getId();   // Get the current Chat ID

        $data = [                                  // Set up the new message data
            'chat_id' => $chat_id,                 // Set Chat ID to send the message to
            'text'    => 'This is simple command', // Set message to send
        ];

        return Request::sendMessage($data);        // Send message!
    }
}

I did try that "dummy" 'cause I did find a similar answer (https://github.com/php-telegram-bot/core/issues/436 ) . Of course I would delete that dummy, but before ot this I would that my chat could display... "This is a simple command" but chat doesn't show nothing (and no error in php / apache2 log)

Thank you for your support!

Most helpful comment

OK,
Probably I did solve, now it works!

I leave answer for some other looking for same / similar issues:

\Longman\TelegramBot\Commands\SystemCommands\CallbackqueryCommand::addCallbackHandler(function (\Longman\TelegramBot\Entities\CallbackQuery $query) use($telegram) {
    $telegram->executeCommand('simple');
});

All 3 comments

Sorry for the UP!
I'm doing my homework but I cannot solve this step.

I did change approach, following @noplanman approach found here: https://github.com/php-telegram-bot/core/pull/540#issue-237032981

I need to say that probably some step I did, but... I have an error in PHP log and cannot solve.

Basically, my hook file is part of a class and this is:

<?php
namespace Domapi\Script;

// Load composer
require '/var/www/html/src/Tbot/vendor/autoload.php';

class Telegram extends \Domapi\Script\BaseScript {
// some stuff
  private function getHook() {

        $commands_paths = array ( '/var/www/html/src/Tbot/vendor/longman/telegram-bot/src/Commands/CustomCommands' );

        $continue = false;

        if ( isset ( $_GET['secret'] )  ) {

            if ( $_GET['secret'] == $this->getSecret() ) {

                $continue = true;

            }

        }

        if ( $continue == true ) {

            try {

                    // Create Telegram API object
                    //$telegram = new Longman\TelegramBot\Telegram($bot_api_key, $bot_username);
                    $telegram = $this->getTelegram();

                    $telegram->addCommandsPaths($commands_paths);

                    $telegram->enableAdmins( $this->getAdmin() );

                    // Requests Limiter (tries to prevent reaching Telegram API limits)
                    $telegram->enableLimiter();

                    \Longman\TelegramBot\Commands\SystemCommands\CallbackqueryCommand::addCallbackHandler(function (\Longman\TelegramBot\Commands\SystemCommands\CallbackQuery $query) {
                        $telegram->executeCommand('simplenocb');
                    });

                    $telegram->handle();
                } catch (Longman\TelegramBot\Exception\TelegramException $e) {
                    // Silence is golden!
                    // log telegram errors
                    // echo $e->getMessage();
                }

        }

    }
}

CallbackqueryCommand is the basic here: https://github.com/php-telegram-bot/core/blob/master/src/Commands/SystemCommands/CallbackqueryCommand.php

But in apache error log I have:

PHP Fatal error: Uncaught TypeError: Argument 1 passed to Domapi\\Script\\Telegram::Domapi\\Script\\{closure}() must be an instance of Longman\\TelegramBot\\Commands\\SystemCommands\\CallbackQuery, instance of Longman\\TelegramBot\\Entities\\CallbackQuery given, called in /var/www/html/src/Tbot/vendor/longman/telegram-bot/src/Commands/SystemCommands/CallbackqueryCommand.php on line 56 and defined in /var/www/html/src/Domapi/Script/Telegram.php:190\nStack trace:\n#0 /var/www/html/src/Tbot/vendor/longman/telegram-bot/src/Commands/SystemCommands/CallbackqueryCommand.php(56): Domapi\\Script\\Telegram->Domapi\\Script\\{closure}(Object(Longman\\TelegramBot\\Entities\\CallbackQuery))\n#1 /var/www/html/src/Tbot/vendor/longman/telegram-bot/src/Commands/Command.php(173): Longman\\TelegramBot\\Commands\\SystemCommands\\CallbackqueryCommand->execute()\n#2 /var/www/html/src/Tbot/vendor/longman/telegram-bot/src/Telegram.php(494): Longman\\TelegramBot\\Commands\\Command->preExecute()\n#3 /var/www/html/src/Tbot/vendor/longman/telegram-bot/src/Telegram.php(462): Longman\\T in /var/www/html/src/Domapi/Script/Telegram.php on line 190

If instead I edit Callbackhandler as following (found CallbackQuery method on Entities namespace):

\Longman\TelegramBot\Commands\SystemCommands\CallbackqueryCommand::addCallbackHandler(function (\Longman\TelegramBot\Entities\CallbackQuery $query) {
    $telegram->executeCommand('simplenocb');
});

PHP complains for $telegram->executeCommand('simplenocb') with

Uncaught Error: Call to a member function executeCommand() on null in /var/www/html/src/Domapi/Script/Telegram.php:172\nStack trace:\n#0 /var/www/html/src/Tbot/vendor/longman/telegram-bot/src/Commands/SystemCommands/CallbackqueryCommand.php(56): Domapi\\Script\\Telegram->Domapi\\Script\\{closure}(Object(Longman\\TelegramBot\\Entities\\CallbackQuery))\n#1 /var/www/html/src/Tbot/vendor/longman/telegram-bot/src/Commands/Command.php(173): Longman\\TelegramBot\\Commands\\SystemCommands\\CallbackqueryCommand->execute()\n#2 /var/www/html/src/Tbot/vendor/longman/telegram-bot/src/Telegram.php(494): Longman\\TelegramBot\\Commands\\Command->preExecute()\n#3 /var/www/html/src/Tbot/vendor/longman/telegram-bot/src/Telegram.php(462): Longman\\TelegramBot\\Telegram->executeCommand('callbackquery')\n#4 /var/www/html/src/Tbot/vendor/longman/telegram-bot/src/Telegram.php(388): Longman\\TelegramBot\\Telegram->processUpdate(Object(Longman\\TelegramBot\\Entities\\Update))\n#5 /var/www/html/src/Domapi/Script/Telegram.php(175): Longman\\TelegramBot\\Telegram->ha in /var/www/html/src/Domapi/Script/Telegram.php on line 172

But of course $telegram is instead available, because I can handle simple commands (for simple I mean command without callback) (following line, out of conditional) without issues...

Thank you!

OK,
Probably I did solve, now it works!

I leave answer for some other looking for same / similar issues:

\Longman\TelegramBot\Commands\SystemCommands\CallbackqueryCommand::addCallbackHandler(function (\Longman\TelegramBot\Entities\CallbackQuery $query) use($telegram) {
    $telegram->executeCommand('simple');
});

@sineverba I noticed this line:

$commands_paths = array ( '/var/www/html/src/Tbot/vendor/longman/telegram-bot/src/Commands/CustomCommands' );

Please don't ever change or save anything in / below the vendor folder, as that will all get replaced when updating via composer.
For custom commands, just create an own folder somewhere in the root folder of your project :+1:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

NabiKAZ picture NabiKAZ  路  3Comments

nesttle picture nesttle  路  4Comments

TheSleepySlee picture TheSleepySlee  路  3Comments

Zoha picture Zoha  路  3Comments

Recouse picture Recouse  路  3Comments