перенос из другого репозитория
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					vendor
 | 
				
			||||||
							
								
								
									
										11
									
								
								LICENSE
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										11
									
								
								LICENSE
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
 | 
				
			||||||
 | 
					Version 2, December 2004
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
 | 
				
			||||||
 | 
					TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  0. You just DO WHAT THE FUCK YOU WANT TO.
 | 
				
			||||||
							
								
								
									
										3
									
								
								README.md
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										3
									
								
								README.md
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					# Telegram-robot for registering for tasks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Synchronizes accounts with the site, displays a list of published applications with a selection by date, and also register to tasks
 | 
				
			||||||
							
								
								
									
										28
									
								
								composer.json
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										28
									
								
								composer.json
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "name": "mirzaev/spetsresurs-telegram-registry-requests",
 | 
				
			||||||
 | 
					    "type": "robot",
 | 
				
			||||||
 | 
					    "require": {
 | 
				
			||||||
 | 
					        "triagens/arangodb": "^3.8",
 | 
				
			||||||
 | 
					        "mirzaev/arangodb": "^1.0",
 | 
				
			||||||
 | 
					        "badfarm/zanzara": "^0.9.1",
 | 
				
			||||||
 | 
					        "nyholm/psr7": "^1.8"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "license": "WTFPL",
 | 
				
			||||||
 | 
					    "autoload": {
 | 
				
			||||||
 | 
					        "psr-4": {
 | 
				
			||||||
 | 
					            "mirzaev\\spetsresurs\\telegram\\registry\\requests\\": "mirzaev/spetsresurs/telegram/registry/requests/system/"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "authors": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "name": "Arsen Mirzaev Tatyano-Muradovich",
 | 
				
			||||||
 | 
					            "email": "arsen@mirzaev.sexy"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "minimum-stability": "stable",
 | 
				
			||||||
 | 
					    "config": {
 | 
				
			||||||
 | 
					        "allow-plugins": {
 | 
				
			||||||
 | 
					            "php-http/discovery": true
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1741
									
								
								composer.lock
									
									
									
										generated
									
									
									
										Executable file
									
								
							
							
						
						
									
										1741
									
								
								composer.lock
									
									
									
										generated
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										4210
									
								
								mirzaev/spetsresurs/telegram/registry/requests/system/emojis.txt
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										4210
									
								
								mirzaev/spetsresurs/telegram/registry/requests/system/emojis.txt
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										675
									
								
								mirzaev/spetsresurs/telegram/registry/requests/system/public/robot.php
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										675
									
								
								mirzaev/spetsresurs/telegram/registry/requests/system/public/robot.php
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,675 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Фреймворк ArangoDB
 | 
				
			||||||
 | 
					use mirzaev\arangodb\connection,
 | 
				
			||||||
 | 
						mirzaev\arangodb\collection,
 | 
				
			||||||
 | 
						mirzaev\arangodb\document;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Библиотека для ArangoDB
 | 
				
			||||||
 | 
					use ArangoDBClient\Document as _document,
 | 
				
			||||||
 | 
						ArangoDBClient\Cursor,
 | 
				
			||||||
 | 
						ArangoDBClient\Statement as _statement;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Фреймворк Telegram
 | 
				
			||||||
 | 
					use Zanzara\Zanzara;
 | 
				
			||||||
 | 
					use Zanzara\Context;
 | 
				
			||||||
 | 
					use Zanzara\Config;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require __DIR__ . '/../../../../../../../vendor/autoload.php';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$arangodb = new connection(require __DIR__ . '/../settings/arangodb.php');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ini_set('error_reporting', E_ALL);
 | 
				
			||||||
 | 
					ini_set('display_errors', 1);
 | 
				
			||||||
 | 
					ini_set('display_startup_errors', 1); */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function escape(string $text)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return str_replace(
 | 
				
			||||||
 | 
							[
 | 
				
			||||||
 | 
								'#',
 | 
				
			||||||
 | 
								'*',
 | 
				
			||||||
 | 
								'_',
 | 
				
			||||||
 | 
								'=',
 | 
				
			||||||
 | 
								'.',
 | 
				
			||||||
 | 
								'[',
 | 
				
			||||||
 | 
								']',
 | 
				
			||||||
 | 
								'(',
 | 
				
			||||||
 | 
								')',
 | 
				
			||||||
 | 
								'-',
 | 
				
			||||||
 | 
								'>',
 | 
				
			||||||
 | 
								'<'
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
							[
 | 
				
			||||||
 | 
								'\#',
 | 
				
			||||||
 | 
								'\*',
 | 
				
			||||||
 | 
								'\_',
 | 
				
			||||||
 | 
								'\\=',
 | 
				
			||||||
 | 
								'\.',
 | 
				
			||||||
 | 
								'\[',
 | 
				
			||||||
 | 
								'\]',
 | 
				
			||||||
 | 
								'\(',
 | 
				
			||||||
 | 
								'\)',
 | 
				
			||||||
 | 
								'\-',
 | 
				
			||||||
 | 
								'\>',
 | 
				
			||||||
 | 
								'\<'
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
							$text
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Авторизация
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param string $id Идентификатор Telegram
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return _document|null|false (инстанция аккаунта, если подключен и авторизован; null, если не подключен; false, если подключен но неавторизован)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function authorization(string $id): _document|null|false
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						global $arangodb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (collection::init($arangodb->session, 'telegram')) {
 | 
				
			||||||
 | 
							if ($telegram = collection::search($arangodb->session, sprintf("FOR d IN telegram FILTER d.id == '%s' RETURN d", $id))) {
 | 
				
			||||||
 | 
								if ($telegram->number === null) return null;
 | 
				
			||||||
 | 
								else if (
 | 
				
			||||||
 | 
									$telegram->active
 | 
				
			||||||
 | 
									&& collection::init($arangodb->session, 'account')
 | 
				
			||||||
 | 
									&& $account = collection::search(
 | 
				
			||||||
 | 
										$arangodb->session,
 | 
				
			||||||
 | 
										sprintf(
 | 
				
			||||||
 | 
											"FOR d IN account FILTER d.number == '%s' RETURN d",
 | 
				
			||||||
 | 
											$telegram->number,
 | 
				
			||||||
 | 
											$telegram->getId()
 | 
				
			||||||
 | 
										)
 | 
				
			||||||
 | 
									)
 | 
				
			||||||
 | 
								) return $account;
 | 
				
			||||||
 | 
								else return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else throw new exception('Не удалось инициализировать коллекцию');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Сотрудник
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param string $id Идентификатор аккаунта
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return _document|null|false (инстанция аккаунта, если подключен и авторизован; null, если не подключен; false, если подключен но неавторизован)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function worker(string $id): _document|null|false
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						global $arangodb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return collection::search(
 | 
				
			||||||
 | 
							$arangodb->session,
 | 
				
			||||||
 | 
							sprintf(
 | 
				
			||||||
 | 
								<<<'AQL'
 | 
				
			||||||
 | 
									FOR d IN worker
 | 
				
			||||||
 | 
										LET e = (
 | 
				
			||||||
 | 
											FOR e IN account_edge_worker
 | 
				
			||||||
 | 
												FILTER e._from == '%s'
 | 
				
			||||||
 | 
												SORT e.created DESC, e._key DESC
 | 
				
			||||||
 | 
												LIMIT 1
 | 
				
			||||||
 | 
												RETURN e
 | 
				
			||||||
 | 
										)
 | 
				
			||||||
 | 
										FILTER d._id == e[0]._to
 | 
				
			||||||
 | 
										SORT d.created DESC, d._key DESC
 | 
				
			||||||
 | 
										LIMIT 1
 | 
				
			||||||
 | 
										RETURN d
 | 
				
			||||||
 | 
								AQL,
 | 
				
			||||||
 | 
								$id
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function registration(string $id, string $number): bool
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						global $arangodb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (collection::init($arangodb->session, 'telegram')) {
 | 
				
			||||||
 | 
							if ($telegram = collection::search($arangodb->session, sprintf("FOR d IN telegram FILTER d.id == '%s' RETURN d", $id))) {
 | 
				
			||||||
 | 
								// Найден аккаунт
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Запись номера
 | 
				
			||||||
 | 
								$telegram->number = $number;
 | 
				
			||||||
 | 
								if (!document::update($arangodb->session, $telegram)) return false;
 | 
				
			||||||
 | 
							} else if (
 | 
				
			||||||
 | 
								$number === null
 | 
				
			||||||
 | 
								|| !$telegram = collection::search(
 | 
				
			||||||
 | 
									$arangodb->session,
 | 
				
			||||||
 | 
									sprintf(
 | 
				
			||||||
 | 
										"FOR d IN telegram FILTER d._id == '%s' RETURN d",
 | 
				
			||||||
 | 
										document::write($arangodb->session,	'telegram', ['id' => $id, 'active' => false, 'number' => $number])
 | 
				
			||||||
 | 
									)
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
							) return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Инициализация ребра: account -> telegram
 | 
				
			||||||
 | 
							if (
 | 
				
			||||||
 | 
								collection::init($arangodb->session, 'account')
 | 
				
			||||||
 | 
								&& ($account = collection::search(
 | 
				
			||||||
 | 
									$arangodb->session,
 | 
				
			||||||
 | 
									sprintf(
 | 
				
			||||||
 | 
										"FOR d IN account FILTER d.number == '%d' RETURN d",
 | 
				
			||||||
 | 
										$telegram->number
 | 
				
			||||||
 | 
									)
 | 
				
			||||||
 | 
								))
 | 
				
			||||||
 | 
								&& collection::init($arangodb->session, 'connection', true)
 | 
				
			||||||
 | 
								&& (collection::search(
 | 
				
			||||||
 | 
									$arangodb->session,
 | 
				
			||||||
 | 
									sprintf(
 | 
				
			||||||
 | 
										"FOR d IN connection FILTER d._from == '%s' && d._to == '%s' RETURN d",
 | 
				
			||||||
 | 
										$account->getId(),
 | 
				
			||||||
 | 
										$telegram->getId()
 | 
				
			||||||
 | 
									)
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
									?? collection::search(
 | 
				
			||||||
 | 
										$arangodb->session,
 | 
				
			||||||
 | 
										sprintf(
 | 
				
			||||||
 | 
											"FOR d IN connection FILTER d._id == '%s' RETURN d",
 | 
				
			||||||
 | 
											document::write(
 | 
				
			||||||
 | 
												$arangodb->session,
 | 
				
			||||||
 | 
												'connection',
 | 
				
			||||||
 | 
												['_from' => $account->getId(), '_to' => $telegram->getId()]
 | 
				
			||||||
 | 
											)
 | 
				
			||||||
 | 
										)
 | 
				
			||||||
 | 
									))
 | 
				
			||||||
 | 
							) {
 | 
				
			||||||
 | 
								// Инициализировано ребро: account -> telegram
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Активация
 | 
				
			||||||
 | 
								$telegram->active = true;
 | 
				
			||||||
 | 
								return document::update($arangodb->session, $telegram);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else throw new exception('Не удалось инициализировать коллекцию');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function generateAuthenticationKeyboard(): array
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return [
 | 
				
			||||||
 | 
							'reply_markup' =>	[
 | 
				
			||||||
 | 
								'keyboard' => [
 | 
				
			||||||
 | 
									[
 | 
				
			||||||
 | 
										['text' => '🔐 Аутентификация', 'request_contact' => true]
 | 
				
			||||||
 | 
									]
 | 
				
			||||||
 | 
								],
 | 
				
			||||||
 | 
								'resize_keyboard' => true
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function generateMenu(Context $ctx): void
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ($account = authorization($ctx->getMessage()?->getFrom()?->getId() ?? $ctx->getCallbackQuery()->getFrom()->getId())) {
 | 
				
			||||||
 | 
							// Успешная авторизация
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							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->sendMessage('👋 Здравствуйте, ' . preg_replace('/([._\-()!#])/', '\\\$1', $account->name['first']), [
 | 
				
			||||||
 | 
									'reply_markup' => [
 | 
				
			||||||
 | 
										'inline_keyboard' => [
 | 
				
			||||||
 | 
											[
 | 
				
			||||||
 | 
												['text' => '🔍 Активные заявки', 'callback_data' => 'day']
 | 
				
			||||||
 | 
											]
 | 
				
			||||||
 | 
										],
 | 
				
			||||||
 | 
										'remove_keyboard' => true
 | 
				
			||||||
 | 
									]
 | 
				
			||||||
 | 
								])->then(function ($message) use ($ctx) {
 | 
				
			||||||
 | 
									$ctx->setChatDataItem("menu", $message);
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Прочитать заявки из ArangoDB
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param int $amount Количество
 | 
				
			||||||
 | 
					 * @param ?string $date За какую дату (unixtime)
 | 
				
			||||||
 | 
					 * @param int $page Страница
 | 
				
			||||||
 | 
					 * @param _document $worker Сотрудник
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return Cursor
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function requests(int $amount = 5, ?string $date = null, int $page = 1, _document $worker): Cursor
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						global $arangodb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Инициализация значения даты по умолчанию
 | 
				
			||||||
 | 
						$date ??= time();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Фильтрация номера страницы
 | 
				
			||||||
 | 
						if ($page < 1) $page = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Инициализация номера страницы для вычислний
 | 
				
			||||||
 | 
						--$page;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Инициализация сдвига
 | 
				
			||||||
 | 
						$offset = $page === 0 ? 0 : $page * $amount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (new _statement(
 | 
				
			||||||
 | 
							$arangodb->session,
 | 
				
			||||||
 | 
							[
 | 
				
			||||||
 | 
								'query' => sprintf(
 | 
				
			||||||
 | 
									// d.date < %s там специально, не менять на <=
 | 
				
			||||||
 | 
									"FOR d IN task FILTER ((d.date >= %s && d.date < %s && d.start >= '05:00') || (d.date >= %s && d.date < %s && d.start < '05:00')) && d.worker == null && d.market != null && d.confirmed != true && d.published == true && d.completed != true && (FOR m IN market FILTER m.id == d.market && IS_ARRAY(m.bans) SORT m.created DESC, m._key DESC LIMIT 1 RETURN !POSITION(m.bans, \"%s\"))[0] SORT d.created DESC, d._key DESC LIMIT %d, %d RETURN d",
 | 
				
			||||||
 | 
									$from = (new DateTime("@$date"))->setTime(0, 0)->format('U'),
 | 
				
			||||||
 | 
									$to = (new DateTime("@$date"))->modify('+1 day')->setTime(0, 0)->format('U'),
 | 
				
			||||||
 | 
									$to,
 | 
				
			||||||
 | 
									(new DateTime("@$date"))->modify('+2 day')->setTime(0, 0)->format('U'),
 | 
				
			||||||
 | 
									$worker->id,
 | 
				
			||||||
 | 
									$offset,
 | 
				
			||||||
 | 
									$amount + $offset - ($page > 0)
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
								"batchSize" => 1000,
 | 
				
			||||||
 | 
								"sanitize"	=> true
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						))->execute();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function generateEmojis(): string
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return '&#' . hexdec(trim(array_rand(file(__DIR__ . '/../emojis.txt')))) . ';';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function requests_next(Context $ctx): void
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						$ctx->getChatDataItem('requests_page')->then(function ($page) use ($ctx) {
 | 
				
			||||||
 | 
							$ctx->setChatDataItem('requests_page', ($page ?? 1) + 1)->then(function () use ($ctx, $page) {
 | 
				
			||||||
 | 
								search($ctx);
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function requests_previous(Context $ctx): void
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						$ctx->getChatDataItem('requests_page')->then(function ($page) use ($ctx) {
 | 
				
			||||||
 | 
							$ctx->setChatDataItem('requests_page', ($page ?? 2) - 1)->then(function () use ($ctx) {
 | 
				
			||||||
 | 
								search($ctx);
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (($account = authorization($ctx->getCallbackQuery()->getFrom()->getId())) instanceof _document) {
 | 
				
			||||||
 | 
							// Авторизован
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							$ctx->getChatDataItem("request_confirmation_target")->then(function ($_key) use ($ctx, $arangodb, $account) {
 | 
				
			||||||
 | 
								// Прочитана запрашиваемая заявка
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Инициализация инстанции task в базе данных (выбранного задания)
 | 
				
			||||||
 | 
								$task = collection::search($arangodb->session, sprintf("FOR d IN task FILTER d._key == '%s' && d.published == true && d.completed != true && worker == null RETURN d", $_key));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if ($task instanceof _document) {
 | 
				
			||||||
 | 
									// Найдена заявка (подразумевается, что не занята)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if ($worker ??= worker($account->getId())) {
 | 
				
			||||||
 | 
										// Найден сотрудник
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// Запись идентификатора нового сотрудника
 | 
				
			||||||
 | 
										$task->worker = $worker->id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// Снятие с публикации
 | 
				
			||||||
 | 
										$task->published = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										if (document::update($arangodb->session, $task)) {
 | 
				
			||||||
 | 
											// Записано обновление в базу данных
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											$ctx->getChatDataItem("request_all")->then(function ($requests = []) use ($ctx) {
 | 
				
			||||||
 | 
												// Удаление сообщений связанных с запросом
 | 
				
			||||||
 | 
												foreach ($requests ?? [] as $_message) $ctx->deleteMessage($_message->getChat()->getId(), $_message->getMessageId());
 | 
				
			||||||
 | 
											});
 | 
				
			||||||
 | 
											$ctx->setChatDataItem("request_all", []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											$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);
 | 
				
			||||||
 | 
											});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											// End of the process
 | 
				
			||||||
 | 
											$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) {
 | 
				
			||||||
 | 
										generateMenu($ctx);
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
								} else $ctx->sendMessage("❎ *Не удалось принять заявку:* \#$_key", ['reply_markup' =>	['remove_keyboard' => true]])->then(function () use ($ctx) {
 | 
				
			||||||
 | 
									generateMenu($ctx);
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function request_rejected(Context $ctx): void
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						$ctx->getChatDataItem("request_confirmation_target")->then(function ($_key) 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);
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 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");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function search(Context $ctx): void
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						global $arangodb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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 {
 | 
				
			||||||
 | 
								// Активен аккаунт
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								$ctx->getChatDataItem('requests_page')->then(function ($page) use ($ctx, $arangodb, $worker) {
 | 
				
			||||||
 | 
									// Найдена текущая страница
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// Значение страницы по умолчанию
 | 
				
			||||||
 | 
									if (empty($page)) {
 | 
				
			||||||
 | 
										$page = 1;
 | 
				
			||||||
 | 
										$ctx->setChatDataItem('requests_page', 1);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									$generate = function ($date) use ($ctx, $page, $arangodb, $worker) {
 | 
				
			||||||
 | 
										// Поиск заявок в ArangoDB
 | 
				
			||||||
 | 
										$tasks = requests(4, (string) $date, $page, $worker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// Подсчёт количества прочитанных заявок из базы данных
 | 
				
			||||||
 | 
										$count = $tasks->getCount();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// Проверка существования избытка
 | 
				
			||||||
 | 
										$excess = $count > 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// Обрезка заявок до размера страницы (3 заявки на 1 странице)
 | 
				
			||||||
 | 
										$tasks = array_slice($tasks->getAll(), 0, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										if ($count === 0) {
 | 
				
			||||||
 | 
											$ctx->sendMessage('📦 *Заявок нет*')->then(function ($message) use ($ctx) {
 | 
				
			||||||
 | 
												$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 ($message) $ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId());
 | 
				
			||||||
 | 
												$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());
 | 
				
			||||||
 | 
														$ctx->setChatDataItem("request_all", [])->then(function () use ($ctx, $arangodb, $tasks, $excess, $page) {
 | 
				
			||||||
 | 
															foreach ($tasks as $i => $task) {
 | 
				
			||||||
 | 
																// Перебор найденных заявок
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
																if (($market = collection::search(
 | 
				
			||||||
 | 
																	$arangodb->session,
 | 
				
			||||||
 | 
																	sprintf(
 | 
				
			||||||
 | 
																		"FOR d IN market FILTER d.id == '%s' RETURN d",
 | 
				
			||||||
 | 
																		$task->market
 | 
				
			||||||
 | 
																	)
 | 
				
			||||||
 | 
																)) instanceof _document) {
 | 
				
			||||||
 | 
																	// Найден магазин	
 | 
				
			||||||
 | 
																	$ctx->getChatDataItem("request_$i")->then(function ($message) use ($ctx, $task, $market, $tasks, $i, $page, $excess) {
 | 
				
			||||||
 | 
																		// Удаление предыдущего сообщения на этой позиции
 | 
				
			||||||
 | 
																		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(); */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
																			// Отправка сообщения
 | 
				
			||||||
 | 
																			$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) {
 | 
				
			||||||
 | 
																				// Запись сообщения в кеш (на случай необходимости его удаления при смене страницы)
 | 
				
			||||||
 | 
																				$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->setChatDataItem("request_all", $requests = ($requests ?? []) + [count($requests) => $message])->then(function () use ($ctx, $tasks, $i, $page, $excess) {
 | 
				
			||||||
 | 
																							if ($i === array_key_last($tasks)) {
 | 
				
			||||||
 | 
																								// End of the process
 | 
				
			||||||
 | 
																								$ctx->endConversation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
																								// Удаление предыдущего меню
 | 
				
			||||||
 | 
																								$ctx->getChatDataItem("request_menu")->then(function ($message) use ($ctx, $page, $excess) {
 | 
				
			||||||
 | 
																									if ($message) $ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId());
 | 
				
			||||||
 | 
																									$ctx->setChatDataItem("request_menu", null)->then(function () use ($ctx, $page, $excess) {
 | 
				
			||||||
 | 
																										// Инициализация буфера для меню поиска
 | 
				
			||||||
 | 
																										$keyboard = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
																										// Генерация кнопки: "Предыдущая страница"
 | 
				
			||||||
 | 
																										if ($page > 1) $keyboard[] = ['text' => 'Назад', 'callback_data' => 'requests_previous'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
																										// Генерация кнопки: "Отображённая страница"
 | 
				
			||||||
 | 
																										$keyboard[] = ['text' => $page, 'callback_data' => 'requests_current'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
																										// Генерация кнопки: "Следующая страница"
 | 
				
			||||||
 | 
																										if ($excess) $keyboard[] = ['text' => 'Вперёд', 'callback_data' => 'requests_next'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
																										// Отправка меню
 | 
				
			||||||
 | 
																										$ctx->sendMessage('🔍 Выберите заявку', [
 | 
				
			||||||
 | 
																											'reply_markup' => [
 | 
				
			||||||
 | 
																												'inline_keyboard' => [
 | 
				
			||||||
 | 
																													$keyboard
 | 
				
			||||||
 | 
																												]
 | 
				
			||||||
 | 
																											]
 | 
				
			||||||
 | 
																										])->then(function ($message) use ($ctx) {
 | 
				
			||||||
 | 
																											// Запись сообщения в кеш (на случай необходимости его удаления при смене страницы)
 | 
				
			||||||
 | 
																											$ctx->setChatDataItem("request_menu", $message);
 | 
				
			||||||
 | 
																										});
 | 
				
			||||||
 | 
																									});
 | 
				
			||||||
 | 
																								});
 | 
				
			||||||
 | 
																							}
 | 
				
			||||||
 | 
																						});
 | 
				
			||||||
 | 
																					});
 | 
				
			||||||
 | 
																				});
 | 
				
			||||||
 | 
																			});
 | 
				
			||||||
 | 
																		});
 | 
				
			||||||
 | 
																	});
 | 
				
			||||||
 | 
																}
 | 
				
			||||||
 | 
															}
 | 
				
			||||||
 | 
														});
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
 | 
												});
 | 
				
			||||||
 | 
											});
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// Инициализация даты и генерация
 | 
				
			||||||
 | 
									$ctx->getChatDataItem('requests_date')->then(function ($old) use ($ctx, $generate) {
 | 
				
			||||||
 | 
										$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));
 | 
				
			||||||
 | 
										else $generate($old);
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$config = new Config();
 | 
				
			||||||
 | 
					$config->setParseMode(Config::PARSE_MODE_MARKDOWN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$bot = new Zanzara(require(__DIR__ . '/../settings/key.php'), $config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$stop = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$bot->onUpdate(function (Context $ctx) use (&$stop): void {
 | 
				
			||||||
 | 
						$message = $ctx->getMessage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (
 | 
				
			||||||
 | 
							isset($message)
 | 
				
			||||||
 | 
							&& ($contact = $message->getContact())
 | 
				
			||||||
 | 
							&& $contact->getUserId() === $message->getFrom()->getId()
 | 
				
			||||||
 | 
						) {
 | 
				
			||||||
 | 
							// Передан контакт со своими данными (подразумевается второй шаг аутентификации и запуск регистрации)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Запуск регистрации
 | 
				
			||||||
 | 
							if (registration($contact->getUserId(), $contact->getPhoneNumber())) {
 | 
				
			||||||
 | 
								// Успешная регистрация
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								$ctx->sendMessage('✅ *Аккаунт подключен*', ['reply_markup' =>	['remove_keyboard' => true]])->then(function () use ($ctx) {
 | 
				
			||||||
 | 
									generateMenu($ctx);
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								$stop = true;
 | 
				
			||||||
 | 
							} else $ctx->sendMessage('⛔ *Вы не авторизованы*', generateAuthenticationKeyboard());
 | 
				
			||||||
 | 
						} else if ($message?->getText() !== '🔐 Аутентификация' && !authorization($message?->getFrom()?->getId() ?? $ctx->getCallbackQuery()->getFrom()->getId())) {
 | 
				
			||||||
 | 
							$ctx->sendMessage('⛔ *Вы не авторизованы*', generateAuthenticationKeyboard());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							$stop = true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$bot->onCommand('start', function (Context $ctx) use ($stop): void {
 | 
				
			||||||
 | 
						if ($stop) return;
 | 
				
			||||||
 | 
						$ctx->getChatDataItem("request_all")->then(function ($requests = []) use ($ctx) {
 | 
				
			||||||
 | 
							// Удаление сообщений связанных с запросом
 | 
				
			||||||
 | 
							foreach ($requests ?? [] as $_message) $ctx->deleteMessage($_message->getChat()->getId(), $_message->getMessageId());
 | 
				
			||||||
 | 
							$ctx->setChatDataItem("request_all", []);
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						$ctx->getChatDataItem("menu")->then(function ($message) use ($ctx) {
 | 
				
			||||||
 | 
							// Удаление главного меню
 | 
				
			||||||
 | 
							if ($message) $ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId());
 | 
				
			||||||
 | 
							$ctx->setChatDataItem("menu", null);
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						$ctx->getChatDataItem("request_day")->then(function ($message) use ($ctx) {
 | 
				
			||||||
 | 
							// Удаление меню выбора даты
 | 
				
			||||||
 | 
							if ($message) $ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId());
 | 
				
			||||||
 | 
							$ctx->setChatDataItem("request_day", null);
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						generateMenu($ctx);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$bot->onCbQueryData(['requests_next'], fn ($ctx) => requests_next($ctx));
 | 
				
			||||||
 | 
					$bot->onCbQueryData(['requests_previous'], fn ($ctx) => requests_previous($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->onCbQueryData(['day'], fn ($ctx) => day($ctx));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$bot->run();
 | 
				
			||||||
							
								
								
									
										3
									
								
								mirzaev/spetsresurs/telegram/registry/requests/system/settings/.gitignore
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										3
									
								
								mirzaev/spetsresurs/telegram/registry/requests/system/settings/.gitignore
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					*
 | 
				
			||||||
 | 
					!.gitignore
 | 
				
			||||||
 | 
					!*.sample
 | 
				
			||||||
@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					return [
 | 
				
			||||||
 | 
					    'endpoint' => 'unix:///var/run/arangodb3/arango.sock',
 | 
				
			||||||
 | 
					    'database' => '',
 | 
				
			||||||
 | 
					    'name' => '',
 | 
				
			||||||
 | 
					    'password' => ''
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					return '';
 | 
				
			||||||
							
								
								
									
										16
									
								
								telegram-robot.service
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										16
									
								
								telegram-robot.service
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					[Unit]
 | 
				
			||||||
 | 
					Description=Telegram-robot
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Wants=network.target
 | 
				
			||||||
 | 
					After=syslog.target network-online.target
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Service]
 | 
				
			||||||
 | 
					ExecStart=sudo -u www-data /usr/bin/php /var/www/spetsresurs-telegram-registry-requests/mirzaev/spetsresurs/telegram/registry/requests/system/public/robot.php
 | 
				
			||||||
 | 
					PIDFile=/var/run/php/telegram-robot.pid
 | 
				
			||||||
 | 
					RemainAfterExit=no
 | 
				
			||||||
 | 
					RuntimeMaxSec=3600s
 | 
				
			||||||
 | 
					Restart=always
 | 
				
			||||||
 | 
					RestartSec=5s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Install]    
 | 
				
			||||||
 | 
					WantedBy=multi-user.target
 | 
				
			||||||
		Reference in New Issue
	
	Block a user