Skip to content

Commit

Permalink
Merge pull request #8 from CrazyBoy49z/fix_dialog_group
Browse files Browse the repository at this point in the history
Refactor Dialog and DialogManager for improved key generation
  • Loading branch information
lptn authored May 10, 2024
2 parents 4086569 + 130b8eb commit 46864d9
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 30 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ composer.lock
# phpunit
.phpunit.cache
.phpunit.result.cache
.idea
52 changes: 34 additions & 18 deletions src/Dialog.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php declare(strict_types=1);
<?php
declare(strict_types=1);

namespace KootLabs\TelegramBotDialogs;

Expand All @@ -9,7 +10,9 @@

abstract class Dialog
{
protected int $chat_id;
protected int $chatId;

protected int $userId;

/** @var array<string, mixed> Key-value storage to store data between steps. */
protected array $memory = [];
Expand All @@ -29,9 +32,13 @@ abstract class Dialog
/** @var int|null Index of the next step that set manually using jump() method. */
private ?int $afterProceedJumpToIndex = null;

public function __construct(int $chatId, Api $bot = null)
public function __construct(Update $update, Api $bot = null)
{
$this->chat_id = $chatId;
$message = $update->getMessage();

$this->chatId = $message->chat->id;
$this->userId = $message->from->id;

if ($bot) {
$this->bot = $bot;
}
Expand Down Expand Up @@ -59,11 +66,11 @@ final public function start(Update $update): void
*/
final public function proceed(Update $update): void
{
$currentStepIndex = $this->next;
$currentStepIndex = $this->next;

if ($this->isStart()) {
$this->beforeAllStep($update);
}
if ($this->isStart()) {
$this->beforeAllStep($update);
}

if ($this->isEnd()) {
$this->afterAllStep($update);
Expand Down Expand Up @@ -159,24 +166,27 @@ final protected function forget(string $key): void
unset($this->memory[$key]);
}


/** Check if Dialog started */
final public function isStart(): bool
{
return $this->next === 0;
}


/** Check if Dialog ended */
final public function isEnd(): bool
{
return $this->next >= count($this->steps);
}

/** Returns Telegram Chat ID */
final public function getChatId(): int
final public function getChatId(): ?int
{
return $this->chat_id;
return $this->chatId;
}

final public function getUserId(): ?int
{
return $this->userId;
}

/** Get a number of seconds to store state of the Dialog after latest activity on it. */
Expand All @@ -191,7 +201,7 @@ final public function ttl(): int
*/
private function proceedConfiguredStep(array $stepConfig, Update $update, int $currentStepIndex): void
{
if (!isset($stepConfig['name'])) {
if (! isset($stepConfig['name'])) {
throw new InvalidDialogStep('Configurable Dialog step does not contain required “name” value.');
}

Expand All @@ -200,17 +210,17 @@ private function proceedConfiguredStep(array $stepConfig, Update $update, int $c
if (isset($stepConfig['response'])) {
$params = [
'chat_id' => $this->getChatId(),
'text' => $stepConfig['response'],
'text' => $stepConfig['response'],
];

if (!empty($stepConfig['options'])) {
if (! empty($stepConfig['options'])) {
$params = array_merge($params, $stepConfig['options']);
}

$this->bot->sendMessage($params);
}

if (!empty($stepConfig['jump'])) {
if (! empty($stepConfig['jump'])) {
$this->jump($stepConfig['jump']);
}

Expand All @@ -225,9 +235,15 @@ private function proceedConfiguredStep(array $stepConfig, Update $update, int $c
public function __serialize(): array
{
return [
'chat_id' => $this->getChatId(),
'next' => $this->next,
'chatId' => $this->getChatId(),
'userId' => $this->getUserId(),
'next' => $this->next,
'memory' => $this->memory,
];
}

public function getDialogKey(): string
{
return implode('-', [$this->getUserId(), $this->getChatId()]);
}
}
27 changes: 15 additions & 12 deletions src/DialogManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Telegram\Bot\Api;
use Telegram\Bot\Objects\Message;
use Telegram\Bot\Objects\Update;
use Illuminate\Support\Collection;

final class DialogManager
{
Expand Down Expand Up @@ -42,11 +43,9 @@ private function getDialogInstance(Update $update): ?Dialog
return null;
}

$message = $update->getMessage();
assert($message instanceof \Telegram\Bot\Objects\Message);
$chatId = $message->chat->id;
$key = $this->generateDialogKey($update);

$dialog = $this->readDialogState($chatId);
$dialog = $this->readDialogState($key);
$dialog->setBot($this->bot);

return $dialog;
Expand All @@ -67,8 +66,7 @@ public function proceed(Update $update): void
$dialog->proceed($update);

if ($dialog->isEnd()) {
$this->store->delete($dialog->getChatId());
$dialog->proceed($update);
$this->store->delete($dialog->getDialogKey());
} else {
$this->storeDialogState($dialog);
}
Expand All @@ -77,20 +75,25 @@ public function proceed(Update $update): void
/** Whether Dialog exist for a given Update. */
public function exists(Update $update): bool
{
$message = $update->getMessage();
$chatId = $message instanceof Message ? $message->chat->id : null;
return $chatId && $this->store->has($chatId);
$key = $this->generateDialogKey($update);

return $key && $this->store->has($key);
}

/** Store all Dialog. */
private function storeDialogState(Dialog $dialog): void
{
$this->store->set($dialog->getChatId(), $dialog, $dialog->ttl());
$this->store->set($dialog->getDialogKey(), $dialog, $dialog->ttl());
}

/** Restore Dialog. */
private function readDialogState(int $chatId): Dialog
private function readDialogState($key): Dialog
{
return $this->store->get($key);
}

private function generateDialogKey(Update $update): string
{
return $this->store->get($chatId);
return implode('-', [$update->getMessage()->from->id, $update->getChat()->id]);
}
}

0 comments on commit 46864d9

Please sign in to comment.