Squashed commit message
Some checks are pending
Telegram Mini App Shop Builder / Compute version metadata (push) Waiting to run
Telegram Mini App Shop Builder / Run Frontend tests (push) Waiting to run
Telegram Mini App Shop Builder / Run Backend tests (push) Waiting to run
Telegram Mini App Shop Builder / Run PHP_CodeSniffer (push) Waiting to run
Telegram Mini App Shop Builder / Build module. (push) Blocked by required conditions
Telegram Mini App Shop Builder / release (push) Blocked by required conditions

This commit is contained in:
2026-03-11 22:08:41 +03:00
commit 3cc82e45f0
585 changed files with 65605 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
<?php
declare(strict_types=1);
namespace Bastion\Handlers;
use App\Exceptions\TelegramCustomerNotFoundException;
use App\Exceptions\TelegramCustomerWriteNotAllowedException;
use App\Models\TelegramCustomer;
use GuzzleHttp\Exception\GuzzleException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Acme\ECommerceFramework\Http\Request;
use Acme\ECommerceFramework\Telegram\TelegramService;
use Psr\Log\LoggerInterface;
use RuntimeException;
/**
* Handler для отправки сообщений Telegram-пользователям из админ-панели
*
* @package Bastion\Handlers
*/
class SendMessageHandler
{
private TelegramService $telegramService;
private TelegramCustomer $telegramCustomerModel;
private LoggerInterface $logger;
public function __construct(
TelegramService $telegramService,
TelegramCustomer $telegramCustomerModel,
LoggerInterface $logger
) {
$this->telegramService = $telegramService;
$this->telegramCustomerModel = $telegramCustomerModel;
$this->logger = $logger;
}
/**
* Отправить сообщение Telegram-пользователю
*
* @param Request $request HTTP запрос с id (ID записи в таблице) и message
* @return JsonResponse JSON ответ с результатом операции
* @throws TelegramCustomerNotFoundException Если пользователь не найден
* @throws TelegramCustomerWriteNotAllowedException Если пользователь не разрешил писать в PM
* @throws RuntimeException Если данные невалидны
* @throws \Exception
* @throws GuzzleException
*/
public function sendMessage(Request $request): JsonResponse
{
$customerId = $this->extractCustomerId($request);
$message = $this->extractMessage($request);
// Находим запись по ID
$customer = $this->telegramCustomerModel->findById($customerId);
if (! $customer) {
throw new TelegramCustomerNotFoundException($customerId);
}
$telegramUserId = (int) $customer['telegram_user_id'];
// Проверяем, что пользователь разрешил писать ему в PM
if (! $customer['allows_write_to_pm']) {
throw new TelegramCustomerWriteNotAllowedException($telegramUserId);
}
// Отправляем сообщение (telegram_user_id используется как chat_id)
// Используем пустую строку для parse_mode чтобы отправлять обычный текст
$this->telegramService->sendMessage(
$telegramUserId,
$message,
);
$this->logger->info('Message sent to Telegram user', [
'oc_customer_id' => $customerId,
'telegram_user_id' => $telegramUserId,
'message_length' => strlen($message),
]);
return new JsonResponse([
'success' => true,
'message' => 'Message sent successfully',
]);
}
/**
* Извлечь ID записи из запроса
*
* @param Request $request HTTP запрос
* @return int ID записи в таблице acmeshop_customers
* @throws RuntimeException Если ID отсутствует или невалиден
*/
private function extractCustomerId(Request $request): int
{
$jsonData = $request->json();
$customerId = isset($jsonData['id']) ? (int) $jsonData['id'] : 0;
if ($customerId <= 0) {
throw new RuntimeException('Customer ID is required and must be positive');
}
return $customerId;
}
/**
* Извлечь сообщение из запроса
*
* @param Request $request HTTP запрос
* @return string Текст сообщения
* @throws RuntimeException Если сообщение отсутствует или пустое
*/
private function extractMessage(Request $request): string
{
$jsonData = $request->json();
$message = isset($jsonData['message']) ? trim($jsonData['message']) : '';
if (empty($message)) {
throw new RuntimeException('Message is required and cannot be empty');
}
return $message;
}
}