Skip to content

Fix Telegram::runCommands for User and nested calls #1223

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ Exclamation symbols (:exclamation:) note something of importance e.g. breaking c
### Added
- Bot API 5.2 (Payments 2.0).
### Changed
- `Telegram::runCommands` returns array of `ServerResponse` objects of executed commands.
### Deprecated
### Removed
### Fixed
- Regex for namespace extraction from custom command classes.
- Nested and user-triggered `Telegram::runCommands`.
### Security

## [0.72.0] - 2021-04-16
Expand Down
82 changes: 51 additions & 31 deletions src/Telegram.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
use Longman\TelegramBot\Commands\Command;
use Longman\TelegramBot\Commands\SystemCommand;
use Longman\TelegramBot\Commands\UserCommand;
use Longman\TelegramBot\Entities\Chat;
use Longman\TelegramBot\Entities\ServerResponse;
use Longman\TelegramBot\Entities\Update;
use Longman\TelegramBot\Entities\User;
use Longman\TelegramBot\Exception\TelegramException;
use PDO;
use RecursiveDirectoryIterator;
Expand Down Expand Up @@ -1115,63 +1117,81 @@ public function enableLimiter(array $options = []): Telegram
*
* @param array $commands
*
* @return ServerResponse[]
*
* @throws TelegramException
*/
public function runCommands(array $commands): void
public function runCommands(array $commands): array
{
if (empty($commands)) {
throw new TelegramException('No command(s) provided!');
}

$this->run_commands = true;

$result = Request::getMe();
// Check if this request has a user Update / comes from Telegram.
if ($userUpdate = $this->update) {
$from = $this->update->getMessage()->getFrom();
$chat = $this->update->getMessage()->getChat();
} else {
// Fall back to the Bot user.
$from = new User([
'id' => $this->getBotId(),
'first_name' => $this->getBotUsername(),
'username' => $this->getBotUsername(),
]);

if ($result->isOk()) {
$result = $result->getResult();
// Try to get "live" Bot info.
$response = Request::getMe();
if ($response->isOk()) {
/** @var User $result */
$result = $response->getResult();

$from = new User([
'id' => $result->getId(),
'first_name' => $result->getFirstName(),
'username' => $result->getUsername(),
]);
}

$bot_id = $result->getId();
$bot_name = $result->getFirstName();
$bot_username = $result->getUsername();
} else {
$bot_id = $this->getBotId();
$bot_name = $this->getBotUsername();
$bot_username = $this->getBotUsername();
}
// Give Bot access to admin commands.
$this->enableAdmin($from->getId());

// Give bot access to admin commands
$this->enableAdmin($bot_id);
// Lock the bot to a private chat context.
$chat = new Chat([
'id' => $from->getId(),
'type' => 'private',
]);
}

$newUpdate = static function ($text = '') use ($bot_id, $bot_name, $bot_username) {
$newUpdate = static function ($text = '') use ($from, $chat) {
return new Update([
'update_id' => 0,
'update_id' => -1,
'message' => [
'message_id' => 0,
'from' => [
'id' => $bot_id,
'first_name' => $bot_name,
'username' => $bot_username,
],
'message_id' => -1,
'date' => time(),
'chat' => [
'id' => $bot_id,
'type' => 'private',
],
'from' => json_decode($from->toJson(), true),
'chat' => json_decode($chat->toJson(), true),
'text' => $text,
],
]);
};

$responses = [];

foreach ($commands as $command) {
$this->update = $newUpdate($command);

// Load up-to-date commands list
if (empty($this->commands_objects)) {
$this->commands_objects = $this->getCommandsList();
}
// Refresh commands list for new Update object.
$this->commands_objects = $this->getCommandsList();

$this->executeCommand($this->update->getMessage()->getCommand());
$responses[] = $this->executeCommand($this->update->getMessage()->getCommand());
}

// Reset Update to initial context.
$this->update = $userUpdate;

return $responses;
}

/**
Expand Down