profileId); if (! $profile) { return; // nothing to do } /** @var SmsSender|null $sender */ $sender = $this->senderId ? SmsSender::find($this->senderId) : null; // Apply Redis throttle from config to avoid provider rate limits $scope = config('services.sms.throttle.scope', 'global'); $provider = config('services.sms.throttle.provider_key', 'smsapi_si'); $allow = (int) config('services.sms.throttle.allow', 30); $every = (int) config('services.sms.throttle.every', 60); $jitter = (int) config('services.sms.throttle.jitter_seconds', 2); $key = $scope === 'per_profile' && $profile ? "sms:{$provider}:{$profile->id}" : "sms:{$provider}"; $log = null; try { Redis::throttle($key)->allow($allow)->every($every)->then(function () use (&$log, $sms, $profile, $sender) { // Send and get log (handles queued->sent/failed transitions internally) $log = $sms->sendRaw( profile: $profile, to: $this->to, content: $this->content, sender: $sender, countryCode: $this->countryCode, deliveryReport: $this->deliveryReport, clientReference: $this->clientReference, ); }, function () use ($jitter) { return $this->release(max(1, rand(1, $jitter))); }); } catch (\Throwable $e) { // Fallback if Redis is unavailable in test or local env $log = $sms->sendRaw( profile: $profile, to: $this->to, content: $this->content, sender: $sender, countryCode: $this->countryCode, deliveryReport: $this->deliveryReport, clientReference: $this->clientReference, ); } // If invoked from the case UI with a selected template, create an Activity if ($this->templateId && $this->clientCaseId && $log) { try { /** @var SmsTemplate|null $template */ $template = SmsTemplate::find($this->templateId); /** @var ClientCase|null $case */ $case = ClientCase::find($this->clientCaseId); if ($template && $case) { $note = ''; if ($log->status === 'sent') { $note = sprintf('Št: %s | Telo: %s', (string) $this->to, (string) $this->content); } elseif ($log->status === 'failed') { $note = sprintf( 'Št: %s | Telo: %s | Napaka: %s', (string) $this->to, (string) $this->content, 'SMS ni bil poslan!' ); } $case->activities()->create([ 'note' => $note, 'action_id' => $template->action_id, 'decision_id' => $template->decision_id, 'user_id' => $this->userId, ]); } } catch (\Throwable $e) { \Log::warning('SendSmsJob activity creation failed', [ 'error' => $e->getMessage(), 'client_case_id' => $this->clientCaseId, 'template_id' => $this->templateId, ]); } } } }