| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- <?php
- namespace Controllers;
- use Libs\Logger;
- use Libs\Payload;
- use Libs\Roles;
- use Libs\Validator;
- use Models\IntegrationsModel;
- use Models\UnipileMessagesModel;
- use Models\UserModel;
- use Psr\Http\Message\ServerRequestInterface;
- use Services\UnipileClient;
- class InteractionSendMessageController
- {
- private UserModel $userModel;
- private IntegrationsModel $integrationsModel;
- private UnipileMessagesModel $messagesModel;
- private UnipileClient $unipileClient;
- public function __construct()
- {
- $this->userModel = new UserModel();
- $this->integrationsModel = new IntegrationsModel();
- $this->messagesModel = new UnipileMessagesModel();
- $this->unipileClient = new UnipileClient();
- }
- public function __invoke(ServerRequestInterface $request)
- {
- $userId = (int) ($request->getAttribute('user_id') ?? 0);
- $userEmail = (string) ($request->getAttribute('user_email') ?? '');
- $userRole = mb_strtolower(trim((string) ($request->getAttribute('user_role') ?? '')));
- $body = json_decode((string) $request->getBody(), true) ?: [];
- $conversationId = (int) ($body['conversation_id'] ?? 0);
- $text = trim((string) ($body['text'] ?? ''));
- if ($userId <= 0) {
- return Payload::fail('Unauthorized: Missing authenticated user', [], 'E_VALIDATE', 401);
- }
- $validator = (new Validator(['conversation_id' => $conversationId, 'text' => $text]))
- ->required('conversation_id')->intRange('conversation_id', 1)
- ->required('text')->maxLength('text', 4000);
- if ($validator->fails()) {
- return Payload::fail($validator->firstError(), [], 'E_VALIDATE', 400);
- }
- if (!$this->unipileClient->isConfigured()) {
- return Payload::fail('Unipile is not configured', [], 'E_GENERIC', 500);
- }
- try {
- $companyId = $this->userModel->getCompanyIdByUserId($userId);
- if ($companyId === null) {
- return Payload::fail('User not found', [], 'E_NOT_FOUND', 404);
- }
- $conversation = $this->messagesModel->getConversationForSending($companyId, $conversationId);
- if ($conversation === null) {
- return Payload::fail('Conversation not found', [], 'E_NOT_FOUND', 404);
- }
- if (!$this->canSend($companyId, $userEmail, $userRole, $conversation)) {
- return Payload::fail('Forbidden: insufficient permissions', [], 'E_FORBIDDEN', 403);
- }
- if (!(bool) ($conversation['integration_is_connected'] ?? false)) {
- return Payload::fail('Integration is not connected', [], 'E_VALIDATE', 400);
- }
- $chatId = (string) ($conversation['conversation_external_id'] ?? '');
- if ($chatId === '') {
- return Payload::fail('Conversation is missing external chat id', [], 'E_VALIDATE', 400);
- }
- $response = $this->unipileClient->sendTextMessage($chatId, $text);
- $message = $this->messagesModel->createOutboundLocalMessage($conversationId, $response, $text);
- $this->messagesModel->updateConversationAfterOutbound($conversationId, $text);
- return Payload::ok([
- 'message_id' => (int) ($message['message_id'] ?? 0),
- 'unipile' => $response,
- ]);
- } catch (\Throwable $e) {
- Logger::error('Failed to send WhatsApp message through Unipile', ['error' => $e->getMessage()]);
- return Payload::fail('Failed to send message', [], 'E_GENERIC', 500);
- }
- }
- private function canSend(int $companyId, string $userEmail, string $userRole, array $conversation): bool
- {
- if (in_array($userRole, [Roles::ADMIN, Roles::MANAGER], true)) {
- return true;
- }
- if ($userRole !== Roles::OPERATOR) {
- return false;
- }
- $operatorId = $this->integrationsModel->getOperatorIdByUserEmail($companyId, $userEmail);
- if ($operatorId <= 0) {
- return false;
- }
- return (int) ($conversation['operator_id'] ?? 0) === $operatorId;
- }
- }
|