Estados
Os estados permitem que você gerencie conversas com os usuários. O pacote suporta dois tipos de estados: estado de chat e estado de usuário.
Conceito de Estado
Seção intitulada “Conceito de Estado”Um estado é um estado nomeado com dados opcionais armazenados em cache. Ele permite que você:
- Crie conversas em múltiplas etapas
- Filtre rotas pelo estado atual
- Salve contexto entre mensagens
Tipos de Estados
Seção intitulada “Tipos de Estados”- Estado de chat — comum para todos os usuários em um chat
- Estado de usuário — individual para cada usuário
Trabalhando com StateManager
Seção intitulada “Trabalhando com StateManager”Obtendo Estado
Seção intitulada “Obtendo Estado”use HybridGram\\Core\\State\\StateManagerInterface;
$stateManager = app(StateManagerInterface::class);$chat = $data->getChat();
// Obter estado de chat$chatState = $stateManager->getChatState($chat);if ($chatState) { $stateName = $chatState->getName(); $stateData = $chatState->getData();}
// Obter estado de usuário$user = $data->getUser();if ($user) { $userState = $stateManager->getUserState($chat, $user);}Definindo Estado
Seção intitulada “Definindo Estado”// Definir estado de chat$stateManager->setChatState( chat: $chat, state: 'awaiting_name', ttl: 3600, // Tempo de vida em segundos (opcional, padrão 24 horas) data: ['step' => 1] // Dados adicionais (opcional));
// Definir estado de usuário$stateManager->setUserState( chat: $chat, user: $user, state: 'filling_profile', ttl: 7200, data: ['name' => 'John', 'age' => null]);Limpando Estado
Seção intitulada “Limpando Estado”// Limpar estado de chat$stateManager->clearChatState($chat);
// Limpar estado de usuário$stateManager->clearUserState($chat, $user);Verificando Estado
Seção intitulada “Verificando Estado”// Verificar estado específicoif ($stateManager->isChatInState($chat, 'awaiting_input')) { // ...}
if ($stateManager->isUserInState($chat, $user, 'filling_form')) { // ...}
// Verificar qualquer um dos estadosif ($stateManager->isChatInAnyState($chat, ['awaiting_name', 'awaiting_email'])) { // ...}Usando em Rotas
Seção intitulada “Usando em Rotas”Filtrando Rotas por Estado
Seção intitulada “Filtrando Rotas por Estado”TelegramRouter::onTextMessage(function(TextMessageData $data) { // Esta rota é acionada apenas se o chat estiver em estado 'awaiting_name'}, '*', function(TextMessageData $data) { $stateManager = app(\\HybridGram\\Core\\State\\StateManagerInterface::class); $chat = $data->getChat();
return $stateManager->isChatInState($chat, 'awaiting_name');});Ou usando o método de rota:
TelegramRouter::forBot('main') ->onMessage(function(TextMessageData $data) { // Processamento }) ->fromChatState('awaiting_name'); // Rota é acionada apenas a partir deste estadoDefinindo Estado via Rota
Seção intitulada “Definindo Estado via Rota”TelegramRouter::onCommand('/start', function(CommandData $data) { $stateManager = app(\\HybridGram\\Core\\State\\StateManagerInterface::class); $stateManager->setChatState($data->getChat(), 'main_menu');
// Enviar resposta});Ou via middleware:
use HybridGram\\Http\\Middlewares\\SetStateTelegramRouteMiddleware;
TelegramRouter::onCommand('/start', function(CommandData $data) { // ...})->middleware(new SetStateTelegramRouteMiddleware('main_menu'));Exemplos de Uso
Seção intitulada “Exemplos de Uso”Formulário Multi-etapas
Seção intitulada “Formulário Multi-etapas”// Etapa 1: InícioTelegramRouter::onCommand('/register', function(CommandData $data) { $stateManager = app(\\HybridGram\\Core\\State\\StateManagerInterface::class); $telegram = app(\\HybridGram\\Telegram\\TelegramBotApi::class);
$stateManager->setChatState($data->getChat(), 'awaiting_name');
$telegram->sendMessage( $data->getChat()->id, 'Digite seu nome:' );});
// Etapa 2: Obtendo nomeTelegramRouter::forBot('main') ->onTextMessage(function(TextMessageData $data) { $stateManager = app(\\HybridGram\\Core\\State\\StateManagerInterface::class); $telegram = app(\\HybridGram\\Telegram\\TelegramBotApi::class); $chat = $data->getChat();
$name = $data->message;
// Salvar nome nos dados de estado $stateManager->setChatState( chat: $chat, state: 'awaiting_email', data: ['name' => $name] );
$telegram->sendMessage($chat->id, 'Digite seu email:'); }) ->fromChatState('awaiting_name');
// Etapa 3: Obtendo emailTelegramRouter::forBot('main') ->onTextMessage(function(TextMessageData $data) { $stateManager = app(\\HybridGram\\Core\\State\\StateManagerInterface::class); $telegram = app(\\HybridGram\\Telegram\\TelegramBotApi::class); $chat = $data->getChat();
$currentState = $stateManager->getChatState($chat); $name = $currentState?->getData()['name'] ?? 'Unknown'; $email = $data->message;
// Salvar usuário // ... sua lógica de salvamento
// Limpar estado $stateManager->clearChatState($chat);
$telegram->sendMessage( $chat->id, "Obrigado, {$name}! Seu email: {$email}" ); }) ->fromChatState('awaiting_email');Cancelando Processo
Seção intitulada “Cancelando Processo”TelegramRouter::onCommand('/cancel', function(CommandData $data) { $stateManager = app(\\HybridGram\\Core\\State\\StateManagerInterface::class); $telegram = app(\\HybridGram\\Telegram\\TelegramBotApi::class); $chat = $data->getChat();
// Limpar todos os estados $stateManager->clearChatState($chat); if ($user = $data->getUser()) { $stateManager->clearUserState($chat, $user); }
$telegram->sendMessage($chat->id, 'Operação cancelada');});Trabalhando com Dados de Estado
Seção intitulada “Trabalhando com Dados de Estado”TelegramRouter::onTextMessage(function(TextMessageData $data) { $stateManager = app(\\HybridGram\\Core\\State\\StateManagerInterface::class); $chat = $data->getChat();
$currentState = $stateManager->getChatState($chat);
if ($currentState) { $stateData = $currentState->getData() ?? []; $step = ($stateData['step'] ?? 0) + 1;
// Atualizar estado com novos dados $stateManager->setChatState( chat: $chat, state: $currentState->getName(), data: array_merge($stateData, ['step' => $step]) ); }})->fromChatState('filling_form');Excluindo Estados
Seção intitulada “Excluindo Estados”Você pode criar uma rota que funciona apenas se o chat NÃO estiver em um estado específico:
TelegramRouter::forBot('main') ->onCommand('/help', function(CommandData $data) { // Mostrar ajuda }) ->exceptChatState('processing'); // Não mostrar durante o processamentoEstados de Usuário
Seção intitulada “Estados de Usuário”Para o processamento individual de cada usuário, use estados de usuário:
TelegramRouter::onCallbackQuery(function(CallbackQueryData $data) { $stateManager = app(\\HybridGram\\Core\\State\\StateManagerInterface::class); $chat = $data->getChat(); $user = $data->getUser();
// Definir estado para usuário específico $stateManager->setUserState( chat: $chat, user: $user, state: 'selecting_item', data: ['item_id' => $data->params[0]] );});Tempo de Vida do Estado
Seção intitulada “Tempo de Vida do Estado”Por padrão, os estados são armazenados por 24 horas. Você pode alterar isso:
$stateManager->setChatState( chat: $chat, state: 'temporary_state', ttl: 300 // 5 minutos);Próximos Passos
Seção intitulada “Próximos Passos”- Middleware — usando middleware para gerenciamento de estado
- Enviando Mensagens — enviando respostas para usuários