Skip to content

Commit 65ada67

Browse files
committed
Merge remote-tracking branch 'origin/main'
2 parents dd5f1d8 + 1ccf701 commit 65ada67

2 files changed

Lines changed: 219 additions & 0 deletions

File tree

llms-full.txt

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7529,6 +7529,134 @@ $tg->msg("Новая подпись к новому фото")
75297529

75307530
---
75317531

7532+
---
7533+
url: 'https://zenithgram.github.io/using/fsm.md'
7534+
description: Создание диалогов и пошаговых сценариев с помощью FSM (Finite State Machine).
7535+
---
7536+
7537+
# Машина состояний (FSM / Диалоги)
7538+
7539+
Часто боту нужно запросить у пользователя несколько данных последовательно: имя, возраст, город и фото. Реализовывать это через бесконечные `if/else` и проверки базы данных неудобно.
7540+
7541+
В **ZenithGram** встроена поддержка **FSM (Finite State Machine)**, которая позволяет легко создавать линейные диалоги.
7542+
7543+
## Подготовка
7544+
7545+
Для работы с состояниями необходимо подключить **Хранилище (Storage)**. Библиотека поставляется с встроенным `FileStorage` (хранение в JSON-файлах), но вы можете реализовать свой интерфейс для Redis или базы данных.
7546+
7547+
```php
7548+
<?php
7549+
require_once __DIR__ . '/vendor/autoload.php';
7550+
use ZenithGram\ZenithGram\ZG;
7551+
use ZenithGram\ZenithGram\Bot;
7552+
use ZenithGram\ZenithGram\Storage\FileStorage;
7553+
7554+
$tg = ZG::create('ТОКЕН_БОТА');
7555+
$bot = new Bot($tg);
7556+
7557+
// Инициализируем хранилище в Bot
7558+
$bot->setStorage(new FileStorage());
7559+
7560+
// Или напрямую в ZG
7561+
$tg->setStorage(new FileStorage());
7562+
```
7563+
7564+
## Основные методы
7565+
7566+
* `$tg->step('название_шага')` — Переводит пользователя в указанное состояние.
7567+
* `$bot->onState('название_шага')` — Обработчик, который сработает, только если пользователь находится в этом состоянии.
7568+
* `$tg->session(['ключ' => 'значение'])` — Сохраняет данные в сессию пользователя.
7569+
* `$tg->session()` — Возвращает массив всех сохраненных данных.
7570+
* `$tg->endStep()` — Сбрасывает состояние и очищает данные сессии.
7571+
7572+
## Пример: Анкета регистрации
7573+
7574+
Пример: создадим бота, который спрашивает Имя, Возраст и Город.
7575+
7576+
### Шаг 1: Вход в диалог
7577+
7578+
Создаем команду, которая инициирует процесс.
7579+
7580+
```php
7581+
$bot->onBotCommand('reg', '/reg')
7582+
->func(function(ZG $tg) {
7583+
$tg->reply("Давайте знакомиться! Как вас зовут?");
7584+
// Переводим пользователя в состояние ожидания имени
7585+
$tg->step('wait_name');
7586+
});
7587+
```
7588+
7589+
### Шаг 2: Обработка Имени
7590+
7591+
Создаем обработчик для состояния `wait_name`. Он перехватит любое текстовое сообщение пользователя.
7592+
7593+
```php
7594+
$bot->onState('wait_name')
7595+
->func(function(ZG $tg, string $name) {
7596+
// Сохраняем имя в сессию
7597+
$tg->session(['name' => $name]);
7598+
7599+
$tg->reply("Приятно познакомиться, {$name}. Сколько вам лет?");
7600+
// Переходим к следующему шагу
7601+
$tg->step('wait_age');
7602+
});
7603+
```
7604+
7605+
### Шаг 3: Обработка Возраста (с валидацией)
7606+
7607+
Здесь мы проверим, ввел ли пользователь число.
7608+
7609+
```php
7610+
$bot->onState('wait_age')
7611+
->func(function(ZG $tg, string $age) {
7612+
// Простая валидация
7613+
if (!is_numeric($age)) {
7614+
$tg->reply("Пожалуйста, введите возраст цифрами.");
7615+
return; // Не меняем шаг, пользователь останется в wait_age
7616+
}
7617+
7618+
$tg->session(['age' => $age]);
7619+
7620+
$tg->reply("Отлично! Из какого вы города?");
7621+
$tg->step('wait_city');
7622+
});
7623+
```
7624+
7625+
### Шаг 4: Финал
7626+
7627+
Получаем город, выводим итог и завершаем диалог.
7628+
7629+
```php
7630+
$bot->onState('wait_city')
7631+
->func(function(ZG $tg, string $city) {
7632+
// Сохраняем последнее значение
7633+
$tg->session(['city' => $city]);
7634+
7635+
// Получаем все накопленные данные
7636+
$data = $tg->session();
7637+
7638+
$text = "🎉 Регистрация завершена!\n\n" .
7639+
"👤 Имя: {$data['name']}\n" .
7640+
"🎂 Возраст: {$data['age']}\n" .
7641+
"🏙 Город: {$data['city']}";
7642+
7643+
$tg->reply($text);
7644+
7645+
// Сбрасываем состояние и очищаем данные
7646+
$tg->endStep();
7647+
});
7648+
```
7649+
7650+
## Важные моменты
7651+
7652+
1. **Приоритет:** Обработчик `onState` имеет приоритет над обычными `onText` и `onCommand`. Если пользователь находится в состоянии, бот будет искать соответствующий `onState` в первую очередь.
7653+
2. **Типы обновлений:** `onState` перехватывает как текст, так и нажатия кнопок (`callback_query`), если пользователь находится в заданном состоянии.
7654+
3. **Очистка:** Всегда вызывайте `endStep()`, когда диалог логически завершен, иначе пользователь "застрянет" в последнем состоянии.
7655+
7656+
Добавьте этот пример в конец файла или в соответствующий раздел.
7657+
7658+
---
7659+
75327660
---
75337661
url: 'https://zenithgram.github.io/using/errorHandler.md'
75347662
description: >-
@@ -8802,6 +8930,96 @@ $bot->btn('broadcast_admin', '📢 Рассылка')->text('Введите те
88028930
$bot->run();
88038931
```
88048932

8933+
## Бот-анкета (Диалоги / FSM)
8934+
8935+
> Пример бота, который проводит опрос пользователя, сохраняет данные между шагами и поддерживает кнопку "Отмена".
8936+
8937+
```php
8938+
<?php
8939+
require_once __DIR__ . '/vendor/autoload.php';
8940+
use ZenithGram\ZenithGram\ZG;
8941+
use ZenithGram\ZenithGram\Bot;
8942+
use ZenithGram\ZenithGram\Storage\FileStorage;
8943+
use ZenithGram\ZenithGram\Button;
8944+
8945+
$tg = ZG::create('ТОКЕН_БОТА');
8946+
$bot = new Bot($tg);
8947+
8948+
// 1. Подключаем хранилище (обязательно для FSM)
8949+
$bot->setStorage(new FileStorage());
8950+
8951+
// 2. Команда отмены (доступна всегда)
8952+
// Если пользователь в состоянии диалога, это выведет его оттуда
8953+
$bot->onBotCommand('cancel', '/cancel')
8954+
->func(function(ZG $tg) {
8955+
$tg->reply("Диалог отменен.");
8956+
$tg->endStep(); // Сброс состояния
8957+
});
8958+
8959+
// 3. Старт анкеты
8960+
$bot->onBotCommand('survey', '/survey')
8961+
->func(function(ZG $tg) {
8962+
$tg->msg("Оцените наш сервис от 1 до 5:")
8963+
->inlineKbd([
8964+
[Button::cb('1', '1'), Button::cb('2', '2'), Button::cb('3', '3'), Button::cb('4', '4'), Button::cb('5', '5')]
8965+
])
8966+
->send();
8967+
8968+
// Переходим в состояние ожидания оценки
8969+
$tg->step('wait_rating');
8970+
});
8971+
8972+
// 4. Обработка оценки (Ожидаем нажатие кнопки или текст)
8973+
$bot->onState('wait_rating')
8974+
->func(function(ZG $tg, string $input) {
8975+
// Если это callback (нажатие кнопки), ответим на него
8976+
if ($tg->getType() === 'callback_query') {
8977+
$tg->answerCallbackQuery($tg->getQueryId());
8978+
}
8979+
8980+
// Проверяем ввод
8981+
if (!in_array($input, ['1', '2', '3', '4', '5'])) {
8982+
$tg->reply("Пожалуйста, нажмите на кнопку от 1 до 5.");
8983+
return;
8984+
}
8985+
8986+
// Сохраняем оценку
8987+
$tg->session(['rating' => $input]);
8988+
8989+
$tg->msg("Спасибо! Теперь напишите краткий отзыв (или отправьте /skip, чтобы пропустить):")
8990+
->removeKbd() // Убираем старые клавиатуры если были
8991+
->send();
8992+
8993+
$tg->step('wait_feedback');
8994+
});
8995+
8996+
// 5. Обработка текста отзыва
8997+
$bot->onState('wait_feedback')
8998+
->func(function(ZG $tg, string $text) {
8999+
$data = $tg->session(); // Получаем сохраненную ранее оценку
9000+
$rating = $data['rating'];
9001+
$review = ($text === '/skip') ? 'Без отзыва' : $text;
9002+
9003+
// Формируем отчет
9004+
$report = "📝 <b>Новый отзыв!</b>\n" .
9005+
"⭐ Оценка: {$rating}/5\n" .
9006+
"💬 Текст: " . htmlspecialchars($review);
9007+
9008+
// Отправляем пользователю подтверждение
9009+
$tg->msg("Ваш отзыв принят!\n\n$report")
9010+
->parseMode(\ZenithGram\ZenithGram\Enums\MessageParseMode::HTML)
9011+
->send();
9012+
9013+
// (Опционально) Отправка админу
9014+
// $tg->sendMessage(ADMIN_ID, $report);
9015+
9016+
// Завершаем диалог
9017+
$tg->endStep();
9018+
});
9019+
9020+
$bot->run();
9021+
```
9022+
88059023
### Больше примеров
88069024

88079025
В документации для каждого метода есть примеры его использования.

llms.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
- [Получение обновлений](https://zenithgram.github.io/using/getting-updates.md): Настройка методов получения обновлений: Long Polling для разработки и Webhook для продакшена.
1515
- [Конструктор сообщений](https://zenithgram.github.io/using/messages.md): Работа с Fluent Interface для создания, форматирования и отправки сообщений.
1616
- [Конструктор опросов](https://zenithgram.github.io/using/poll.md): Создание и отправка опросов и викторин.
17+
- [Машина состояний (FSM / Диалоги)](https://zenithgram.github.io/using/fsm.md): Создание диалогов и пошаговых сценариев с помощью FSM (Finite State Machine).
1718
- [Обработчики событий](https://zenithgram.github.io/using/handlers.md): Описание обработчиков из класса Bot
1819
- [Middleware](https://zenithgram.github.io/using/middleware.md): Промежуточное ПО для фильтрации запросов, логирования и проверки прав доступа.
1920
- [Пагинация (Pagination)](https://zenithgram.github.io/using/pagination.md)

0 commit comments

Comments
 (0)