From 12ea04da2e42f007493c68214755d9bbffc50518 Mon Sep 17 00:00:00 2001 From: Yurij Finiv Date: Sun, 30 Jul 2023 17:11:12 +0300 Subject: [PATCH 01/14] Add support laravel 10 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b0d8430..64c59a4 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "homepage": "https://github.com/koot-labs/telegram-bot-dialogs", "require": { "php": ">=8.0", - "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0", + "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0| ^10.0", "irazasyed/telegram-bot-sdk": "^3.1", "predis/predis": "^1.0 || ^2.0" }, From a192c61adc896e34af2b602c3e1359cfdd8d1ebe Mon Sep 17 00:00:00 2001 From: Yurij Finiv Date: Sun, 30 Jul 2023 17:22:35 +0300 Subject: [PATCH 02/14] Add dialog key --- src/Dialog.php | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/Dialog.php b/src/Dialog.php index 9666039..de7ae40 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -9,7 +9,9 @@ abstract class Dialog { - protected int $chat_id; + protected int $chatId; + + protected int $userId; /** @var array Key-value storage to store data between steps. */ protected array $memory = []; @@ -29,9 +31,11 @@ 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; + $this->chatId = $update->getMessage()->getChat()->getId(); + $this->userId = $update->getMessage()->getFrom()->getId(); + if ($bot) { $this->bot = $bot; } @@ -150,7 +154,12 @@ final public function isEnd(): bool /** Returns Telegram Chat ID */ 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. */ @@ -204,4 +213,9 @@ public function __serialize(): array 'memory' => $this->memory, ]; } + + public function getDialogKey() + { + return $this->getUserId().$this->getChatId(); + } } From 6254b46d4ce35ee3586f975fea9bfa10c2ffc088 Mon Sep 17 00:00:00 2001 From: Yurij Finiv Date: Sun, 30 Jul 2023 17:23:44 +0300 Subject: [PATCH 03/14] Fix Dialog key --- src/Dialog.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Dialog.php b/src/Dialog.php index de7ae40..8f5e36c 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -216,6 +216,6 @@ public function __serialize(): array public function getDialogKey() { - return $this->getUserId().$this->getChatId(); + return $this->getUserId().'_'.$this->getChatId(); } } From 1917a266e5c71ef7f427bf799955e8d64448d8b7 Mon Sep 17 00:00:00 2001 From: Yurij Finiv Date: Sun, 30 Jul 2023 17:33:48 +0300 Subject: [PATCH 04/14] Update DialogManager.php --- src/DialogManager.php | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/DialogManager.php b/src/DialogManager.php index 16653d4..92bd3c6 100644 --- a/src/DialogManager.php +++ b/src/DialogManager.php @@ -43,10 +43,10 @@ private function getDialogInstance(Update $update): ?Dialog } $message = $update->getMessage(); - assert($message instanceof \Telegram\Bot\Objects\Message); - $chatId = $message->chat->id; + + $key = $this->generateDialogKey($message) - $dialog = $this->readDialogState($chatId); + $dialog = $this->readDialogState($key); $dialog->setBot($this->bot); return $dialog; @@ -67,7 +67,7 @@ public function proceed(Update $update): void $dialog->proceed($update); if ($dialog->isEnd()) { - $this->store->delete($dialog->getChatId()); + $this->store->delete($dialog->getDialogKey()); } else { $this->storeDialogState($dialog); } @@ -77,19 +77,33 @@ public function proceed(Update $update): void 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($message) + + 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($chatId); + return $this->store->get($key); + } + + private function generateDialogKey(Message $message) + { + $userId = $message->from->id; + $chatId = $message->chat->id; + + if (! $userId && $chatId) { + return null; + } + + return $userId.'-'.$chatId; } } From 11a06a4f7b38e2f9a9987f55b6194b8939be88a9 Mon Sep 17 00:00:00 2001 From: Yurij Finiv Date: Sun, 30 Jul 2023 17:35:40 +0300 Subject: [PATCH 05/14] Update DialogManager.php --- src/DialogManager.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/DialogManager.php b/src/DialogManager.php index 92bd3c6..f6c6ec2 100644 --- a/src/DialogManager.php +++ b/src/DialogManager.php @@ -43,8 +43,8 @@ private function getDialogInstance(Update $update): ?Dialog } $message = $update->getMessage(); - - $key = $this->generateDialogKey($message) + + $key = $this->generateDialogKey($message); $dialog = $this->readDialogState($key); $dialog->setBot($this->bot); @@ -77,9 +77,9 @@ public function proceed(Update $update): void public function exists(Update $update): bool { $message = $update->getMessage(); - - $key = $this->generateDialogKey($message) - + + $key = $this->generateDialogKey($message); + return $key && $this->store->has($key); } @@ -96,14 +96,14 @@ private function readDialogState($key): Dialog } private function generateDialogKey(Message $message) - { + { $userId = $message->from->id; $chatId = $message->chat->id; if (! $userId && $chatId) { return null; } - + return $userId.'-'.$chatId; } } From c59a369476558c13128df7ab3f826896a9175539 Mon Sep 17 00:00:00 2001 From: Yurij Finiv Date: Sun, 30 Jul 2023 17:37:37 +0300 Subject: [PATCH 06/14] Update Dialog.php --- src/Dialog.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Dialog.php b/src/Dialog.php index 8f5e36c..eb4f0b5 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -10,7 +10,7 @@ abstract class Dialog { protected int $chatId; - + protected int $userId; /** @var array Key-value storage to store data between steps. */ @@ -209,6 +209,7 @@ public function __serialize(): array { return [ 'chat_id' => $this->getChatId(), + 'user_id' => $this->getUserId(), 'next' => $this->next, 'memory' => $this->memory, ]; From f4bda71bafde63f61b46dfa6ea3ea5be68ce9aa2 Mon Sep 17 00:00:00 2001 From: Yurij Finiv Date: Sun, 30 Jul 2023 17:42:03 +0300 Subject: [PATCH 07/14] Update Dialog.php --- src/Dialog.php | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/Dialog.php b/src/Dialog.php index eb4f0b5..a96bd2b 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -1,4 +1,5 @@ -chatId = $update->getMessage()->getChat()->getId(); - $this->userId = $update->getMessage()->getFrom()->getId(); + $message = $update->getMessage(); + + $this->chatId = $message->getChat()->getId(); + $this->userId = $message->from->id; if ($bot) { $this->bot = $bot; @@ -63,7 +66,7 @@ final public function start(Update $update): void */ final public function proceed(Update $update): void { - $currentStepIndex = $this->next; + $currentStepIndex = $this->next; if ($this->isEnd()) { return; @@ -157,7 +160,7 @@ final public function getChatId(): int return $this->chatId; } - final public function getUserId(): int + final public function getUserId(): ?int { return $this->userId; } @@ -174,7 +177,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.'); } @@ -183,17 +186,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']); } @@ -210,8 +213,8 @@ public function __serialize(): array return [ 'chat_id' => $this->getChatId(), 'user_id' => $this->getUserId(), - 'next' => $this->next, - 'memory' => $this->memory, + 'next' => $this->next, + 'memory' => $this->memory, ]; } From ef1b30cb813adc5cf910751b1191435bfc8d29dd Mon Sep 17 00:00:00 2001 From: Yurij Finiv Date: Sun, 30 Jul 2023 19:07:01 +0300 Subject: [PATCH 08/14] Update Dialog.php --- src/Dialog.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Dialog.php b/src/Dialog.php index a96bd2b..dd5eb07 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -220,6 +220,6 @@ public function __serialize(): array public function getDialogKey() { - return $this->getUserId().'_'.$this->getChatId(); + return $this->getUserId().'-'.$this->getChatId(); } } From 0bc524864826e1362a905910ea1f918bf6c6947b Mon Sep 17 00:00:00 2001 From: Yurij Finiv Date: Sun, 30 Jul 2023 19:12:00 +0300 Subject: [PATCH 09/14] Update Dialog.php --- src/Dialog.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Dialog.php b/src/Dialog.php index dd5eb07..39fda9d 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -36,7 +36,7 @@ public function __construct(Update $update, Api $bot = null) { $message = $update->getMessage(); - $this->chatId = $message->getChat()->getId(); + $this->chatId = $message->getChat()->id; $this->userId = $message->from->id; if ($bot) { From 8b6a0d18e70b66c8220e8a1e90ef80df0351c120 Mon Sep 17 00:00:00 2001 From: Yurij Finiv Date: Sun, 30 Jul 2023 19:14:55 +0300 Subject: [PATCH 10/14] Update Dialog.php --- src/Dialog.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Dialog.php b/src/Dialog.php index 39fda9d..f3497e1 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -36,7 +36,7 @@ public function __construct(Update $update, Api $bot = null) { $message = $update->getMessage(); - $this->chatId = $message->getChat()->id; + $this->chatId = $message->chat->id; $this->userId = $message->from->id; if ($bot) { From 6aa7b32b3eb9e64a17bc00db1623557403338852 Mon Sep 17 00:00:00 2001 From: Yurij Finiv Date: Sun, 30 Jul 2023 20:51:09 +0300 Subject: [PATCH 11/14] Update Dialog.php --- src/Dialog.php | 232 +++++++++++++------------------------------------ 1 file changed, 58 insertions(+), 174 deletions(-) diff --git a/src/Dialog.php b/src/Dialog.php index f3497e1..f6c6ec2 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -1,225 +1,109 @@ - Key-value storage to store data between steps. */ - protected array $memory = []; - - /** @var \Telegram\Bot\Api Associated Bot instance that will perform API calls. */ - protected Api $bot; - - /** Seconds to store state of the Dialog after latest activity on it. */ - protected int $ttl = 300; - - /** @var list> List of steps. */ - protected array $steps = []; - - /** @var int Index of the next step. */ - protected int $next = 0; - - /** @var int|null Index of the next step that set manually using jump() method. */ - private ?int $afterProceedJumpToIndex = null; - - public function __construct(Update $update, Api $bot = null) + public function __construct(Api $bot, Store $store) { - $message = $update->getMessage(); - - $this->chatId = $message->chat->id; - $this->userId = $message->from->id; - - if ($bot) { - $this->bot = $bot; - } + $this->bot = $bot; + $this->store = $store; } /** - * Specify bot instance (for multi-bot applications). - * @internal DialogManager is the only user of this method. + * Activate a new Dialog. + * to start it - call {@see \KootLabs\TelegramBotDialogs\DialogManager::proceed} */ - final public function setBot(Api $bot): void + public function activate(Dialog $dialog): void { - $this->bot = $bot; + $this->storeDialogState($dialog); } - /** Start Dialog from the begging. */ - final public function start(Update $update): void + /** Use non-default Bot for API calls */ + public function setBot(Api $bot): void { - $this->next = 0; - $this->proceed($update); + $this->bot = $bot; } - /** - * @throws \KootLabs\TelegramBotDialogs\Exceptions\InvalidDialogStep - * @throws \Telegram\Bot\Exceptions\TelegramSDKException - */ - final public function proceed(Update $update): void + private function getDialogInstance(Update $update): ?Dialog { - $currentStepIndex = $this->next; - - if ($this->isEnd()) { - return; + if (! $this->exists($update)) { + return null; } - if (! array_key_exists($currentStepIndex, $this->steps)) { - throw new InvalidDialogStep("Undefined step with index $currentStepIndex."); - } - $stepNameOrConfig = $this->steps[$currentStepIndex]; - - if (is_array($stepNameOrConfig)) { - $this->proceedConfiguredStep($stepNameOrConfig, $update, $currentStepIndex); - } elseif (is_string($stepNameOrConfig)) { - $stepMethodName = $stepNameOrConfig; - - if (! method_exists($this, $stepMethodName)) { - throw new InvalidDialogStep(sprintf('Public method “%s::%s()” is not available.', $this::class, $stepMethodName)); - } - - try { - $this->beforeEveryStep($update, $currentStepIndex); - $this->$stepMethodName($update); - $this->afterEveryStep($update, $currentStepIndex); - } catch (UnexpectedUpdateType) { - return; // skip moving to the next step - } - } else { - throw new InvalidDialogStep('Unknown format of the step.'); - } + $message = $update->getMessage(); - // Step forward only if did not change inside the step handler - $hasJumpedIntoAnotherStep = $this->afterProceedJumpToIndex !== null; - if ($hasJumpedIntoAnotherStep) { - $this->next = $this->afterProceedJumpToIndex; - $this->afterProceedJumpToIndex = null; - } else { - ++$this->next; - } - } + $key = $this->generateDialogKey($message); - /** @experimental Run code before every step. */ - protected function beforeEveryStep(Update $update, int $step): void - { - // override the method to add your logic here - } + $dialog = $this->readDialogState($key); + $dialog->setBot($this->bot); - /** @experimental Run code after every step. */ - protected function afterEveryStep(Update $update, int $step): void - { - // override the method to add your logic here + return $dialog; } - /** Jump to the particular step of the Dialog. */ - final protected function jump(string $stepName): void + /** + * Run next step of the active Dialog. + * This is a thin wrapper for {@see \KootLabs\TelegramBotDialogs\Dialog::proceed} + * to store and restore Dialog state between request-response calls. + */ + public function proceed(Update $update): void { - foreach ($this->steps as $index => $value) { - if ($value === $stepName || (is_array($value) && $value['name'] === $stepName)) { - $this->afterProceedJumpToIndex = $index; - break; - } + $dialog = $this->getDialogInstance($update); + if ($dialog === null) { + return; } - } - /** Move Dialog’s cursor to the end. */ - final public function end(): void - { - $this->next = count($this->steps); - } + $dialog->proceed($update); - /** Remember information for next steps. */ - final protected function remember(string $key, mixed $value): void - { - $this->memory[$key] = $value; + if ($dialog->isEnd()) { + $this->store->delete($dialog->getDialogKey()); + } else { + $this->storeDialogState($dialog); + } } - /** Forget information from next steps. */ - final protected function forget(string $key): void + /** Whether Dialog exist for a given Update. */ + public function exists(Update $update): bool { - unset($this->memory[$key]); - } + $message = $update->getMessage(); - /** Check if Dialog ended */ - final public function isEnd(): bool - { - return $this->next >= count($this->steps); - } + $key = $this->generateDialogKey($message); - /** Returns Telegram Chat ID */ - final public function getChatId(): int - { - return $this->chatId; + return $key && $this->store->has($key); } - final public function getUserId(): ?int + /** Store all Dialog. */ + private function storeDialogState(Dialog $dialog): void { - return $this->userId; + $this->store->set($dialog->getDialogKey(), $dialog, $dialog->ttl()); } - /** Get a number of seconds to store state of the Dialog after latest activity on it. */ - final public function ttl(): int + /** Restore Dialog. */ + private function readDialogState($key): Dialog { - return $this->ttl; + return $this->store->get($key); } - /** - * @throws \Telegram\Bot\Exceptions\TelegramSDKException - * @throws \KootLabs\TelegramBotDialogs\Exceptions\InvalidDialogStep - */ - private function proceedConfiguredStep(array $stepConfig, Update $update, int $currentStepIndex): void + private function generateDialogKey(Message $message) { - if (! isset($stepConfig['name'])) { - throw new InvalidDialogStep('Configurable Dialog step does not contain required “name” value.'); - } - - $this->beforeEveryStep($update, $currentStepIndex); - - if (isset($stepConfig['response'])) { - $params = [ - 'chat_id' => $this->getChatId(), - 'text' => $stepConfig['response'], - ]; - - if (! empty($stepConfig['options'])) { - $params = array_merge($params, $stepConfig['options']); - } - - $this->bot->sendMessage($params); - } - - if (! empty($stepConfig['jump'])) { - $this->jump($stepConfig['jump']); - } - - $this->afterEveryStep($update, $currentStepIndex); + $userId = $message->from->id; + $chatId = $message->chat->id; - if (isset($stepConfig['end']) && $stepConfig['end'] === true) { - $this->end(); + if (! $userId && $chatId) { + return null; } - } - /** @return array */ - public function __serialize(): array - { - return [ - 'chat_id' => $this->getChatId(), - 'user_id' => $this->getUserId(), - 'next' => $this->next, - 'memory' => $this->memory, - ]; - } - - public function getDialogKey() - { - return $this->getUserId().'-'.$this->getChatId(); + return $userId.'-'.$chatId; } } From 6c54ee5465814851e3fe722e1418b4fbb1c234e2 Mon Sep 17 00:00:00 2001 From: Yurij Finiv Date: Sun, 30 Jul 2023 20:52:25 +0300 Subject: [PATCH 12/14] Update Dialog.php --- src/Dialog.php | 232 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 174 insertions(+), 58 deletions(-) diff --git a/src/Dialog.php b/src/Dialog.php index f6c6ec2..21dab69 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -1,109 +1,225 @@ - Key-value storage to store data between steps. */ + protected array $memory = []; + + /** @var \Telegram\Bot\Api Associated Bot instance that will perform API calls. */ + protected Api $bot; + + /** Seconds to store state of the Dialog after latest activity on it. */ + protected int $ttl = 300; + + /** @var list> List of steps. */ + protected array $steps = []; + + /** @var int Index of the next step. */ + protected int $next = 0; + + /** @var int|null Index of the next step that set manually using jump() method. */ + private ?int $afterProceedJumpToIndex = null; + + public function __construct(Update $update, Api $bot = null) { - $this->bot = $bot; - $this->store = $store; + $message = $update->getMessage(); + + $this->chatId = $message->chat->id; + $this->userId = $message->from->id; + + if ($bot) { + $this->bot = $bot; + } } /** - * Activate a new Dialog. - * to start it - call {@see \KootLabs\TelegramBotDialogs\DialogManager::proceed} + * Specify bot instance (for multi-bot applications). + * @internal DialogManager is the only user of this method. */ - public function activate(Dialog $dialog): void + final public function setBot(Api $bot): void { - $this->storeDialogState($dialog); + $this->bot = $bot; } - /** Use non-default Bot for API calls */ - public function setBot(Api $bot): void + /** Start Dialog from the begging. */ + final public function start(Update $update): void { - $this->bot = $bot; + $this->next = 0; + $this->proceed($update); } - private function getDialogInstance(Update $update): ?Dialog + /** + * @throws \KootLabs\TelegramBotDialogs\Exceptions\InvalidDialogStep + * @throws \Telegram\Bot\Exceptions\TelegramSDKException + */ + final public function proceed(Update $update): void { - if (! $this->exists($update)) { - return null; + $currentStepIndex = $this->next; + + if ($this->isEnd()) { + return; } - $message = $update->getMessage(); + if (! array_key_exists($currentStepIndex, $this->steps)) { + throw new InvalidDialogStep("Undefined step with index $currentStepIndex."); + } + $stepNameOrConfig = $this->steps[$currentStepIndex]; + + if (is_array($stepNameOrConfig)) { + $this->proceedConfiguredStep($stepNameOrConfig, $update, $currentStepIndex); + } elseif (is_string($stepNameOrConfig)) { + $stepMethodName = $stepNameOrConfig; + + if (! method_exists($this, $stepMethodName)) { + throw new InvalidDialogStep(sprintf('Public method “%s::%s()” is not available.', $this::class, $stepMethodName)); + } + + try { + $this->beforeEveryStep($update, $currentStepIndex); + $this->$stepMethodName($update); + $this->afterEveryStep($update, $currentStepIndex); + } catch (UnexpectedUpdateType) { + return; // skip moving to the next step + } + } else { + throw new InvalidDialogStep('Unknown format of the step.'); + } - $key = $this->generateDialogKey($message); + // Step forward only if did not change inside the step handler + $hasJumpedIntoAnotherStep = $this->afterProceedJumpToIndex !== null; + if ($hasJumpedIntoAnotherStep) { + $this->next = $this->afterProceedJumpToIndex; + $this->afterProceedJumpToIndex = null; + } else { + ++$this->next; + } + } - $dialog = $this->readDialogState($key); - $dialog->setBot($this->bot); + /** @experimental Run code before every step. */ + protected function beforeEveryStep(Update $update, int $step): void + { + // override the method to add your logic here + } - return $dialog; + /** @experimental Run code after every step. */ + protected function afterEveryStep(Update $update, int $step): void + { + // override the method to add your logic here } - /** - * Run next step of the active Dialog. - * This is a thin wrapper for {@see \KootLabs\TelegramBotDialogs\Dialog::proceed} - * to store and restore Dialog state between request-response calls. - */ - public function proceed(Update $update): void + /** Jump to the particular step of the Dialog. */ + final protected function jump(string $stepName): void { - $dialog = $this->getDialogInstance($update); - if ($dialog === null) { - return; + foreach ($this->steps as $index => $value) { + if ($value === $stepName || (is_array($value) && $value['name'] === $stepName)) { + $this->afterProceedJumpToIndex = $index; + break; + } } + } - $dialog->proceed($update); + /** Move Dialog’s cursor to the end. */ + final public function end(): void + { + $this->next = count($this->steps); + } - if ($dialog->isEnd()) { - $this->store->delete($dialog->getDialogKey()); - } else { - $this->storeDialogState($dialog); - } + /** Remember information for next steps. */ + final protected function remember(string $key, mixed $value): void + { + $this->memory[$key] = $value; } - /** Whether Dialog exist for a given Update. */ - public function exists(Update $update): bool + /** Forget information from next steps. */ + final protected function forget(string $key): void { - $message = $update->getMessage(); + unset($this->memory[$key]); + } - $key = $this->generateDialogKey($message); + /** Check if Dialog ended */ + final public function isEnd(): bool + { + return $this->next >= count($this->steps); + } - return $key && $this->store->has($key); + /** Returns Telegram Chat ID */ + final public function getChatId(): ?int + { + return $this->chatId; } - /** Store all Dialog. */ - private function storeDialogState(Dialog $dialog): void + final public function getUserId(): ?int { - $this->store->set($dialog->getDialogKey(), $dialog, $dialog->ttl()); + return $this->userId; } - /** Restore Dialog. */ - private function readDialogState($key): Dialog + /** Get a number of seconds to store state of the Dialog after latest activity on it. */ + final public function ttl(): int { - return $this->store->get($key); + return $this->ttl; } - private function generateDialogKey(Message $message) + /** + * @throws \Telegram\Bot\Exceptions\TelegramSDKException + * @throws \KootLabs\TelegramBotDialogs\Exceptions\InvalidDialogStep + */ + private function proceedConfiguredStep(array $stepConfig, Update $update, int $currentStepIndex): void { - $userId = $message->from->id; - $chatId = $message->chat->id; + if (! isset($stepConfig['name'])) { + throw new InvalidDialogStep('Configurable Dialog step does not contain required “name” value.'); + } + + $this->beforeEveryStep($update, $currentStepIndex); + + if (isset($stepConfig['response'])) { + $params = [ + 'chat_id' => $this->getChatId(), + 'text' => $stepConfig['response'], + ]; + + if (! empty($stepConfig['options'])) { + $params = array_merge($params, $stepConfig['options']); + } + + $this->bot->sendMessage($params); + } + + if (! empty($stepConfig['jump'])) { + $this->jump($stepConfig['jump']); + } + + $this->afterEveryStep($update, $currentStepIndex); - if (! $userId && $chatId) { - return null; + if (isset($stepConfig['end']) && $stepConfig['end'] === true) { + $this->end(); } + } - return $userId.'-'.$chatId; + /** @return array */ + public function __serialize(): array + { + return [ + 'chatId' => $this->getChatId(), + 'userId' => $this->getUserId(), + 'next' => $this->next, + 'memory' => $this->memory, + ]; + } + + public function getDialogKey() + { + return $this->getUserId().'-'.$this->getChatId(); } } From 896477e4d6c1f5281c2184c0354ed4f1215dbe0e Mon Sep 17 00:00:00 2001 From: Yurij Finiv Date: Mon, 8 Apr 2024 19:02:28 +0300 Subject: [PATCH 13/14] Update DialogManager.php --- src/DialogManager.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/DialogManager.php b/src/DialogManager.php index f6c6ec2..17af940 100644 --- a/src/DialogManager.php +++ b/src/DialogManager.php @@ -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 { @@ -95,10 +96,10 @@ private function readDialogState($key): Dialog return $this->store->get($key); } - private function generateDialogKey(Message $message) + private function generateDialogKey(Message|Collection $message) { - $userId = $message->from->id; - $chatId = $message->chat->id; + $userId = $message->get('from.id',$message->get('user.id') ; + $chatId = $message->get('chat.id', $message->get('user_chat_id')); if (! $userId && $chatId) { return null; From a14a4167d381d36ca2c971e8374460b8fad63eb1 Mon Sep 17 00:00:00 2001 From: Yurij Finiv Date: Mon, 8 Apr 2024 19:04:56 +0300 Subject: [PATCH 14/14] Update DialogManager.php --- src/DialogManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DialogManager.php b/src/DialogManager.php index 17af940..6489f7e 100644 --- a/src/DialogManager.php +++ b/src/DialogManager.php @@ -98,7 +98,7 @@ private function readDialogState($key): Dialog private function generateDialogKey(Message|Collection $message) { - $userId = $message->get('from.id',$message->get('user.id') ; + $userId = $message->get('from.id', $message->get('user.id')); $chatId = $message->get('chat.id', $message->get('user_chat_id')); if (! $userId && $chatId) {