Core: I need to create a keyboard on which I can click only once

Created on 25 Oct 2017  路  7Comments  路  Source: php-telegram-bot/core

I need to create a keyboard on which I can click only once. After the click, the keyboard should be deleted or become unavailable until the server send a response.
Now I do it like this:

class PhonePrepareCalcCommand extends UserCommand
{
    protected $name = 'phonepreparecalc';
    protected $description = 'Mobile phone replenishment - prepare calc amount request';
    protected $usage = '/phonepreparecalc';
    protected $version = '';

    public function execute()
   {
   $message         = $this->getMessage();
   $chat_id         = $message->getChat()->getId();
   $userid              = $message->getFrom()->getId();
   $data['chat_id']         = $chat_id;

    .....................

   $data['parse_mode']  = 'Markdown';
   $data['text']            = 'some text ... ';
   $keybparam           = [
                        'keyboard'              => [ ['Calc'], ['Back'] ],
                        'resize_keyboard'       => true,
                        'one_time_keyboard'     => false,
                        'selective'             => false
                        ];

    $data['reply_markup']   = new Keyboard( $keybparam );
    return Request::sendMessage( $data );
   }
}

In the hook.php:

...
case 'Calc':
        $telegram->executeCommand( 'phonecalcamount' );
        break;
...

When the 'Calc' button is pressed, the command is called. The executing duration of this command is 3-5 seconds. And until this command is executed, the 'Calc' button remains available! And some people click this button again. Is it possible to avoid this as something?

Sincerely, Alexander.

All 7 comments

Instead of

'one_time_keyboard' => false,

try

'one_time_keyboard' => true,

Be aware though, that a user can also just send the Calc message to your bot, which would also execute the command. So best would be to handle (or not) a duplicate click inside your code, which the process is still busy.

Oh, it helped! Thank you so much!
But this partially solves this problem. Is there any option that deletes the button after the click?
In the web interface some craftsmen are able to quickly open the keyboard and click again :D

Ok, to completely remove the keyboard, you can use

'reply_markup' => Keyboard::remove(),

when sending a message.

For example:

...
Request::sendMessage([
    'chat_id'      => $chat_id,
    'text'         => 'Calculation in progress, please wait...',
    'reply_markup' => Keyboard::remove(),
]);
$telegram->executeCommand( 'phonecalcamount' );
break;
...

That will delete the keyboard. But as I said before, the user could also just resend the text Calc to your bot, which would also execute the command again...

You'd have to remember if the command is already being executed, to make sure that it can't be called again before it's complete.

should I place this code in hook.php ?

...
Request::sendMessage([
    'chat_id'      => $chat_id,
    'text'         => 'Calculation in progress, please wait...',
    'reply_markup' => Keyboard::remove(),
]);
$telegram->executeCommand( 'phonecalcamount' );
break;
...

or this part should be in the command PhonePrepareCalcCommand.php:

...
Request::sendMessage([
    'chat_id'      => $chat_id,
    'text'         => 'Calculation in progress, please wait...',
    'reply_markup' => Keyboard::remove(),
]);
...

and this part in hook.php:

...
case 'Calc':
        $telegram->executeCommand( 'phonecalcamount' );
        break;
...

?
But if so, then in the command 'PhonePrepareCalc' I will no longer have a button to 'Calc' or even a keyboard at all?
The first variant I tried - it does not work.

Yes, I remember that the command is performing, thank you. I set the checkbox in the database ( 'Y' ), and check it in the command before executing it.
But due to network problems, this does not always save you. because if the first command is in the process of execution, and the rest of the command stack is in the queue, then the queue starts to be processed only after the result on the first command comes - the result comes and removes the checkbox in database ( 'Y' -> 'N' ) ! and therefore the next command from the packet is also successfully executed :)

I see, so it will need some clever procedure to ensure only a single execution 馃

As for the location of the message to remove the keyboard, inside the command probably makes more sense than the hook.

Either way, why are you putting this code into the hook instead of GenericmessageCommand.php?

Hi noplanman!
Do you have an example of using GenericMessageCommand.php?
Unfortunately, I do not know anything about this yet.
I found this file in the sources, but I do not know how it can be used :(
Can I read about it somewhere?
It seems that I did everything wrong :(

@gmalexmush It's not that you did everything wrong, it just makes sense to split your code into places where it makes more sense 馃槆

Any message that isn't a command will be handled by GenericmessageCommand. So you can make a copy of GenericmessageCommand.php (in SystemCommands folder) to your custom commands folder and put your code in the execute() method there.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

esomkin picture esomkin  路  3Comments

Recouse picture Recouse  路  3Comments

NabiKAZ picture NabiKAZ  路  4Comments

mohsenshahab picture mohsenshahab  路  4Comments

abbe-cipher picture abbe-cipher  路  4Comments