подтверждение заявки

This commit is contained in:
Arsen Mirzaev Tatyano-Muradovich 2024-04-01 04:26:24 +07:00
parent a1855a8d09
commit 8df2ce73c7

View File

@ -23,6 +23,41 @@ $arangodb = new connection(require __DIR__ . '/../settings/arangodb.php');
ini_set('display_errors', 1); ini_set('display_errors', 1);
ini_set('display_startup_errors', 1); */ ini_set('display_startup_errors', 1); */
function escape(string $text)
{
return str_replace(
[
'#',
'*',
'_',
'=',
'.',
'[',
']',
'(',
')',
'-',
'>',
'<'
],
[
'\#',
'\*',
'\_',
'\\=',
'\.',
'\[',
'\]',
'\(',
'\)',
'\-',
'\>',
'\<'
],
$text
);
}
/** /**
* Авторизация * Авторизация
* *
@ -79,7 +114,7 @@ function worker(string $id): _document|null|false
LIMIT 1 LIMIT 1
RETURN e RETURN e
) )
FILTER d._id == e[0]._to && d.active == true FILTER d._id == e[0]._to
SORT d.created DESC, d._key DESC SORT d.created DESC, d._key DESC
LIMIT 1 LIMIT 1
RETURN d RETURN d
@ -172,18 +207,26 @@ function generateMenu(Context $ctx): void
if ($account = authorization($ctx->getMessage()?->getFrom()?->getId() ?? $ctx->getCallbackQuery()->getFrom()->getId())) { if ($account = authorization($ctx->getMessage()?->getFrom()?->getId() ?? $ctx->getCallbackQuery()->getFrom()->getId())) {
// Успешная авторизация // Успешная авторизация
$ctx->sendMessage('👋 Здравствуйте, ' . preg_replace('/([._\-()!#])/', '\\\$1', $account->name['first']), [ if (!$account->active) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
'reply_markup' => [ else if ($account->banned) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
'inline_keyboard' => [ else if (!($worker = worker($account->getId()))->active) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
[ else if ($worker->fired) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
['text' => '🔍 Активные заявки', 'callback_data' => 'day'] else {
] // Активен аккаунт
],
'remove_keyboard' => true $ctx->sendMessage('👋 Здравствуйте, ' . preg_replace('/([._\-()!#])/', '\\\$1', $account->name['first']), [
] 'reply_markup' => [
])->then(function ($message) use ($ctx) { 'inline_keyboard' => [
$ctx->setChatDataItem("menu", $message); [
}); ['text' => '🔍 Активные заявки', 'callback_data' => 'day']
]
],
'remove_keyboard' => true
]
])->then(function ($message) use ($ctx) {
$ctx->setChatDataItem("menu", $message);
});
}
} }
} }
@ -255,82 +298,150 @@ function requests_previous(Context $ctx): void
} }
function request_choose(Context $ctx): void function request_choose(Context $ctx): void
{
if (($account = authorization($ctx->getCallbackQuery()->getFrom()->getId())) instanceof _document) {
// Авторизован
if (!$account->active) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
else if ($account->banned) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
else if (!($worker = worker($account->getId()))->active) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
else if ($worker->fired) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
else {
// Активен аккаунт
// Инициализация ключа инстанции task в базе данных
preg_match('/\->\s#(\d+)\n/', $ctx->getCallbackQuery()->getMessage()->getText(), $matches);
// Запись ключа инстанции task (заявка на которую регистрируется сотрудник)
$ctx->setChatDataItem("request_confirmation_target", $matches[1]);
// Запрос подтверждения
$ctx->sendMessage("⚡ *Подтверждение записи*\n\n" . preg_replace('/(^[^:\s\n\r]+:)/m', '*$1*', preg_replace('/(\\\#\d+)/', '*$1*', escape($ctx->getCallbackQuery()->getMessage()->getText()))) . "\n\n*⚠️ Вы подтверждаете отправку запроса?*", [
'reply_markup' => [
'inline_keyboard' => [
[
['text' => 'Подтвердить', 'callback_data' => 'request_confirmed'],
['text' => 'Отменить', 'callback_data' => 'request_rejected']
]
]
]
])->then(function ($message) use ($ctx) {
// Запись сообщения в кеш (на случай необходимости его удаления)
$ctx->setChatDataItem("request_confirmation", $message);
});
}
}
}
function request_confirmed(Context $ctx): void
{ {
global $arangodb; global $arangodb;
if (($account = authorization($ctx->getCallbackQuery()->getFrom()->getId())) instanceof _document) { if (($account = authorization($ctx->getCallbackQuery()->getFrom()->getId())) instanceof _document) {
// Авторизован // Авторизован
// Инициализация ключа инстанции task в базе данных $ctx->getChatDataItem("request_confirmation_target")->then(function ($_key) use ($ctx, $arangodb, $account) {
preg_match('/\->\s#(\d+)\n/', $ctx->getCallbackQuery()->getMessage()->getText(), $matches); // Прочитана запрашиваемая заявка
$_key = $matches[1];
// Инициализация инстанции task в базе данных (выбранного задания) // Инициализация инстанции task в базе данных (выбранного задания)
$task = collection::search($arangodb->session, sprintf("FOR d IN task FILTER d._key == '%s' && d.published == true && d.completed != true RETURN d", $_key)); $task = collection::search($arangodb->session, sprintf("FOR d IN task FILTER d._key == '%s' && d.published == true && d.completed != true RETURN d", $_key));
if ($worker = worker($account->getId())) { if ($worker ??= worker($account->getId())) {
// Найден сотрудник // Найден сотрудник
// Запись идентификатора нового сотрудника // Запись идентификатора нового сотрудника
$task->worker = $worker->id; $task->worker = $worker->id;
// Снятие с публикации // Снятие с публикации
$task->published = false; $task->published = false;
if (document::update($arangodb->session, $task)) { if (document::update($arangodb->session, $task)) {
// Записано обновление в базу данных // Записано обновление в базу данных
$ctx->getChatDataItem("request_all")->then(function ($requests = []) use ($ctx, $_key) { $ctx->getChatDataItem("request_all")->then(function ($requests = []) use ($ctx) {
// Удаление сообщений связанных с запросом // Удаление сообщений связанных с запросом
foreach ($requests ?? [] as $_message) $ctx->deleteMessage($_message->getChat()->getId(), $_message->getMessageId()); foreach ($requests ?? [] as $_message) $ctx->deleteMessage($_message->getChat()->getId(), $_message->getMessageId());
});
$ctx->setChatDataItem("request_all", []); $ctx->setChatDataItem("request_all", []);
$ctx->sendMessage("✅ *Заявка принята:* \#$_key", ['reply_markup' => ['remove_keyboard' => true]])->then(function () use ($ctx) { $ctx->getChatDataItem("request_confirmation")->then(function ($message) use ($ctx) {
$ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId());
});
$ctx->setChatDataItem("request_confirmation_target", null);
$ctx->sendMessage("✅ *Вы зарегистрировались на заявку:* \#$_key", ['reply_markup' => ['remove_keyboard' => true]])->then(function () use ($ctx) {
generateMenu($ctx); generateMenu($ctx);
}); });
// End of the process // End of the process
$ctx->endConversation(); $ctx->endConversation();
} else $ctx->sendMessage("❎ *Не удалось принять заявку:* \#$_key", ['reply_markup' => ['remove_keyboard' => true]])->then(function () use ($ctx) {
generateMenu($ctx);
}); });
} else $ctx->sendMessage("❎ *Не удалось принять заявку:* \#$_key", ['reply_markup' => ['remove_keyboard' => true]])->then(function () use ($ctx) { } else $ctx->sendMessage("❎ *Не удалось принять заявку:* \#$_key", ['reply_markup' => ['remove_keyboard' => true]])->then(function () use ($ctx) {
generateMenu($ctx); generateMenu($ctx);
}); });
} else $ctx->sendMessage("❎ *Не удалось принять заявку:* \#$_key", ['reply_markup' => ['remove_keyboard' => true]])->then(function () use ($ctx) {
generateMenu($ctx);
}); });
} }
} }
function day(Context $ctx): void function request_rejected(Context $ctx): void
{ {
if (authorization($ctx->getMessage()?->getFrom()?->getId() ?? $ctx->getCallbackQuery()->getFrom()->getId()) instanceof _document) { $ctx->getChatDataItem("request_confirmation_target")->then(function ($_key) use ($ctx) {
// Авторизован // Прочитана запрашиваемая заявка
// Инициализация буфера клавиатуры $ctx->getChatDataItem("request_confirmation")->then(function ($message) use ($ctx) {
$keyboard = []; $ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId());
});
$ctx->setChatDataItem("request_confirmation_target", null);
// Генерация кнопок с выбором даты $ctx->sendMessage("✅ *Вы отменили регистрацию на заявку:* \#$_key", ['reply_markup' => ['remove_keyboard' => true]])->then(function () use ($ctx) {
for ($i = 1, $r = 0; $i < 15; ++$i) $keyboard[$i > 4 * ($r + 1) ? ++$r : $r][] = ['text' => ($date = (new DateTime)->modify("+$i day"))->format('d.m.Y'), 'callback_data' => $date->format('U')]; generateMenu($ctx);
$ctx->setChatDataItem('requests_page', 1)->then(function () use ($ctx, $keyboard) {
// Отправка меню
$ctx->sendMessage('📅 Выберите дату', [
'reply_markup' => [
'inline_keyboard' => $keyboard
]
])->then(function ($message) use ($ctx) {
$ctx->getChatDataItem("menu")->then(function ($message) use ($ctx) {
// Удаление главного меню
if ($message) $ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId());
$ctx->setChatDataItem("menu", null);
});
// Запись сообщения в кеш (на случай необходимости его удаления при смене страницы)
$ctx->setChatDataItem("request_day", $message);
});
}); });
$ctx->nextStep("search"); // End of the process
$ctx->endConversation();
});
}
function day(Context $ctx): void
{
if (($account = authorization($ctx->getMessage()?->getFrom()?->getId() ?? $ctx->getCallbackQuery()->getFrom()->getId())) instanceof _document) {
// Авторизован
if (!$account->active) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
else if ($account->banned) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
else if (!($worker = worker($account->getId()))->active) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
else if ($worker->fired) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
else {
// Активен аккаунт
// Инициализация буфера клавиатуры
$keyboard = [];
// Генерация кнопок с выбором даты
for ($i = 1, $r = 0; $i < 15; ++$i) $keyboard[$i > 4 * ($r + 1) ? ++$r : $r][] = ['text' => ($date = (new DateTime)->modify("+$i day"))->format('d.m.Y'), 'callback_data' => $date->format('U')];
$ctx->setChatDataItem('requests_page', 1)->then(function () use ($ctx, $keyboard) {
// Отправка меню
$ctx->sendMessage('📅 Выберите дату', [
'reply_markup' => [
'inline_keyboard' => $keyboard
]
])->then(function ($message) use ($ctx) {
$ctx->getChatDataItem("menu")->then(function ($message) use ($ctx) {
// Удаление главного меню
if ($message) $ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId());
$ctx->setChatDataItem("menu", null);
});
// Запись сообщения в кеш (на случай необходимости его удаления при смене страницы)
$ctx->setChatDataItem("request_day", $message);
});
});
$ctx->nextStep("search");
}
} }
} }
@ -338,145 +449,153 @@ function search(Context $ctx): void
{ {
global $arangodb; global $arangodb;
if (authorization($ctx->getMessage()?->getFrom()?->getId() ?? $ctx->getCallbackQuery()->getFrom()->getId()) instanceof _document) { if (($account = authorization($ctx->getMessage()?->getFrom()?->getId() ?? $ctx->getCallbackQuery()->getFrom()->getId())) instanceof _document) {
// Авторизован // Авторизован
$ctx->getChatDataItem('requests_page')->then(function ($page) use ($ctx, $arangodb) { if (!$account->active) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
// Найдена текущая страница else if ($account->banned) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
else if (!($worker = worker($account->getId()))->active) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
else if ($worker->fired) $ctx->sendMessage('⚠️ Свяжитесь с оператором');
else {
// Активен аккаунт
// Значение страницы по умолчанию $ctx->getChatDataItem('requests_page')->then(function ($page) use ($ctx, $arangodb) {
if (empty($page)) { // Найдена текущая страница
$page = 1;
$ctx->setChatDataItem('requests_page', 1);
}
$generate = function ($date) use ($ctx, $page, $arangodb) { // Значение страницы по умолчанию
// Поиск заявок в ArangoDB if (empty($page)) {
$tasks = requests(4, (string) $date, $page); $page = 1;
$ctx->setChatDataItem('requests_page', 1);
}
// Подсчёт количества прочитанных заявок из базы данных $generate = function ($date) use ($ctx, $page, $arangodb) {
$count = $tasks->getCount(); // Поиск заявок в ArangoDB
$tasks = requests(4, (string) $date, $page);
// Проверка существования избытка // Подсчёт количества прочитанных заявок из базы данных
$excess = $count > 3; $count = $tasks->getCount();
// Обрезка заявок до размера страницы (3 заявки на 1 странице) // Проверка существования избытка
$tasks = array_slice($tasks->getAll(), 0, 3); $excess = $count > 3;
if ($count === 0) { // Обрезка заявок до размера страницы (3 заявки на 1 странице)
$ctx->sendMessage('📦 *Заявок нет*')->then(function ($message) use ($ctx) { $tasks = array_slice($tasks->getAll(), 0, 3);
$ctx->getChatDataItem("request_all")->then(function ($requests = []) use ($ctx, $message) {
// Удаление сообщений связанных с запросом
foreach ($requests ?? [] as $_message) $ctx->deleteMessage($_message->getChat()->getId(), $_message->getMessageId());
$ctx->setChatDataItem("request_all", $requests = [$message]);
});
});
} else {
// Найдены заявки
$ctx->getChatDataItem("request_day")->then(function ($message) use ($ctx, $arangodb, $tasks, $page, $excess) { if ($count === 0) {
// Удаление предыдущего меню с выбором даты $ctx->sendMessage('📦 *Заявок нет*')->then(function ($message) use ($ctx) {
if ($message) $ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId()); $ctx->getChatDataItem("request_all")->then(function ($requests = []) use ($ctx, $message) {
$ctx->setChatDataItem("request_day", null)->then(function () use ($ctx, $arangodb, $tasks, $page, $excess) {
$ctx->getChatDataItem("request_all")->then(function ($requests = []) use ($ctx, $arangodb, $tasks, $excess, $page) {
// Удаление сообщений связанных с запросом // Удаление сообщений связанных с запросом
foreach ($requests ?? [] as $_message) $ctx->deleteMessage($_message->getChat()->getId(), $_message->getMessageId()); foreach ($requests ?? [] as $_message) $ctx->deleteMessage($_message->getChat()->getId(), $_message->getMessageId());
$ctx->setChatDataItem("request_all", [])->then(function () use ($ctx, $arangodb, $tasks, $excess, $page) { $ctx->setChatDataItem("request_all", $requests = [$message]);
foreach ($tasks as $i => $task) { });
// Перебор найденных заявок });
} else {
// Найдены заявки
if (($market = collection::search( $ctx->getChatDataItem("request_day")->then(function ($message) use ($ctx, $arangodb, $tasks, $page, $excess) {
$arangodb->session, // Удаление предыдущего меню с выбором даты
sprintf( if ($message) $ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId());
"FOR d IN market FILTER d.id == '%s' RETURN d", $ctx->setChatDataItem("request_day", null)->then(function () use ($ctx, $arangodb, $tasks, $page, $excess) {
$task->market $ctx->getChatDataItem("request_all")->then(function ($requests = []) use ($ctx, $arangodb, $tasks, $excess, $page) {
) // Удаление сообщений связанных с запросом
)) instanceof _document) { foreach ($requests ?? [] as $_message) $ctx->deleteMessage($_message->getChat()->getId(), $_message->getMessageId());
// Найден магазин $ctx->setChatDataItem("request_all", [])->then(function () use ($ctx, $arangodb, $tasks, $excess, $page) {
$ctx->getChatDataItem("request_$i")->then(function ($message) use ($ctx, $task, $market, $tasks, $i, $page, $excess) { foreach ($tasks as $i => $task) {
// Удаление предыдущего сообщения на этой позиции // Перебор найденных заявок
if ($message) $ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId());
$ctx->setChatDataItem("request_$i", null)->then(function () use ($ctx, $task, $market, $tasks, $i, $page, $excess) {
// Генерация эмодзи
/* $emoji = generateEmojis(); */
// Отправка сообщения if (($market = collection::search(
$ctx->sendMessage( $arangodb->session,
preg_replace( sprintf(
'/([._\-()!#])/', "FOR d IN market FILTER d.id == '%s' RETURN d",
'\\\$1', $task->market
"*#$task->market* -\> *#{$task->getKey()}*\n" . (new DateTime('@' . $task->date))->format('d.m.Y') . " (" . $task->start . " - " . $task->end . ")\n\n*Город:* $market->city\n*Адрес:* $market->address\n*Работа:* $task->work" . (mb_strlen($task->description) > 0 ? "\n\n$task->description" : '') )
), )) instanceof _document) {
[ // Найден магазин
'reply_markup' => [ $ctx->getChatDataItem("request_$i")->then(function ($message) use ($ctx, $task, $market, $tasks, $i, $page, $excess) {
'inline_keyboard' => [ // Удаление предыдущего сообщения на этой позиции
[ if ($message) $ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId());
['text' => '✅ Отправить запрос', 'callback_data' => 'request_choose'] $ctx->setChatDataItem("request_$i", null)->then(function () use ($ctx, $task, $market, $tasks, $i, $page, $excess) {
// Генерация эмодзи
/* $emoji = generateEmojis(); */
// Отправка сообщения
$ctx->sendMessage(
preg_replace(
'/([._\-()!#])/',
'\\\$1',
"*#$task->market* -\> *#{$task->getKey()}*\n" . (new DateTime('@' . $task->date))->format('d.m.Y') . " (" . $task->start . " - " . $task->end . ")\n\n*Город:* $market->city\n*Адрес:* $market->address\n*Работа:* $task->work" . (mb_strlen($task->description) > 0 ? "\n\n$task->description" : '')
),
[
'reply_markup' => [
'inline_keyboard' => [
[
['text' => '✅ Отправить запрос', 'callback_data' => 'request_choose']
]
] ]
] ]
] ]
] )->then(function ($message) use ($ctx, $tasks, $i, $page, $excess) {
)->then(function ($message) use ($ctx, $tasks, $i, $page, $excess) { // Запись сообщения в кеш (на случай необходимости его удаления при смене страницы)
// Запись сообщения в кеш (на случай необходимости его удаления при смене страницы) $ctx->setChatDataItem("request_$i", $message)->then(function () use ($ctx, $message, $tasks, $i, $page, $excess) {
$ctx->setChatDataItem("request_$i", $message)->then(function () use ($ctx, $message, $tasks, $i, $page, $excess) { $ctx->getChatDataItem("request_all")->then(function ($requests = []) use ($ctx, $message, $tasks, $i, $page, $excess) {
$ctx->getChatDataItem("request_all")->then(function ($requests = []) use ($ctx, $message, $tasks, $i, $page, $excess) { $ctx->setChatDataItem("request_all", $requests = ($requests ?? []) + [count($requests) => $message])->then(function () use ($ctx, $tasks, $i, $page, $excess) {
$ctx->setChatDataItem("request_all", $requests = ($requests ?? []) + [count($requests) => $message])->then(function () use ($ctx, $tasks, $i, $page, $excess) { if ($i === array_key_last($tasks)) {
if ($i === array_key_last($tasks)) { // End of the process
// End of the process $ctx->endConversation();
$ctx->endConversation();
// Удаление предыдущего меню // Удаление предыдущего меню
$ctx->getChatDataItem("request_menu")->then(function ($message) use ($ctx, $page, $excess) { $ctx->getChatDataItem("request_menu")->then(function ($message) use ($ctx, $page, $excess) {
if ($message) $ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId()); if ($message) $ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId());
$ctx->setChatDataItem("request_menu", null)->then(function () use ($ctx, $page, $excess) { $ctx->setChatDataItem("request_menu", null)->then(function () use ($ctx, $page, $excess) {
// Инициализация буфера для меню поиска // Инициализация буфера для меню поиска
$keyboard = []; $keyboard = [];
// Генерация кнопки: "Предыдущая страница" // Генерация кнопки: "Предыдущая страница"
if ($page > 1) $keyboard[] = ['text' => 'Назад', 'callback_data' => 'requests_previous']; if ($page > 1) $keyboard[] = ['text' => 'Назад', 'callback_data' => 'requests_previous'];
// Генерация кнопки: "Отображённая страница" // Генерация кнопки: "Отображённая страница"
$keyboard[] = ['text' => $page, 'callback_data' => 'requests_current']; $keyboard[] = ['text' => $page, 'callback_data' => 'requests_current'];
// Генерация кнопки: "Следующая страница" // Генерация кнопки: "Следующая страница"
if ($excess) $keyboard[] = ['text' => 'Вперёд', 'callback_data' => 'requests_next']; if ($excess) $keyboard[] = ['text' => 'Вперёд', 'callback_data' => 'requests_next'];
// Отправка меню // Отправка меню
$ctx->sendMessage('🔍 Выберите заявку', [ $ctx->sendMessage('🔍 Выберите заявку', [
'reply_markup' => [ 'reply_markup' => [
'inline_keyboard' => [ 'inline_keyboard' => [
$keyboard $keyboard
]
] ]
] ])->then(function ($message) use ($ctx) {
])->then(function ($message) use ($ctx) { // Запись сообщения в кеш (на случай необходимости его удаления при смене страницы)
// Запись сообщения в кеш (на случай необходимости его удаления при смене страницы) $ctx->setChatDataItem("request_menu", $message);
$ctx->setChatDataItem("request_menu", $message); });
}); });
}); });
}); }
} });
}); });
}); });
}); });
}); });
}); });
}); }
} }
} });
}); });
}); });
}); });
}); }
} };
};
// Инициализация даты и генерация // Инициализация даты и генерация
$ctx->getChatDataItem('requests_date')->then(function ($old) use ($ctx, $generate) { $ctx->getChatDataItem('requests_date')->then(function ($old) use ($ctx, $generate) {
$new = $ctx->getCallbackQuery()->getData(); $new = $ctx->getCallbackQuery()->getData();
if ($new === (string) (int) $new && $new <= PHP_INT_MAX && $new >= ~PHP_INT_MAX) $ctx->setChatDataItem('requests_date', $new)->then(fn () => $generate($new)); if ($new === (string) (int) $new && $new <= PHP_INT_MAX && $new >= ~PHP_INT_MAX) $ctx->setChatDataItem('requests_date', $new)->then(fn () => $generate($new));
else $generate($old); else $generate($old);
});
}); });
}); }
} }
} }
@ -540,6 +659,8 @@ $bot->onCommand('start', function (Context $ctx) use ($stop): void {
$bot->onCbQueryData(['requests_next'], fn ($ctx) => requests_next($ctx)); $bot->onCbQueryData(['requests_next'], fn ($ctx) => requests_next($ctx));
$bot->onCbQueryData(['requests_previous'], fn ($ctx) => requests_previous($ctx)); $bot->onCbQueryData(['requests_previous'], fn ($ctx) => requests_previous($ctx));
$bot->onCbQueryData(['request_choose'], fn ($ctx) => request_choose($ctx)); $bot->onCbQueryData(['request_choose'], fn ($ctx) => request_choose($ctx));
$bot->onCbQueryData(['request_confirmed'], fn ($ctx) => request_confirmed($ctx));
$bot->onCbQueryData(['request_rejected'], fn ($ctx) => request_rejected($ctx));
$bot->onCommand('day', fn ($ctx) => day($ctx)); $bot->onCommand('day', fn ($ctx) => day($ctx));
$bot->onCbQueryData(['day'], fn ($ctx) => day($ctx)); $bot->onCbQueryData(['day'], fn ($ctx) => day($ctx));