config->getBool('has_page_notification', true)) { return null; } $title = mb_substr(trim($title), 0, 191); $body = mb_substr(trim($body), 0, 5000); if ($title === '' || $body === '') { return null; } if (! in_array($severity, ['info', 'success', 'warning', 'danger'], true)) { $severity = 'info'; } try { $payload = [ 'title' => $title, 'body' => $body, 'severity' => $severity, 'is_active' => true, 'created_by' => null, 'audience_type' => AppNotificationAudienceService::TYPE_CUSTOMERS, 'segment_keys' => null, 'audience_label' => 'سیستمی — مشتری '.$customerId, 'recipients_count' => 1, ]; if (\Illuminate\Support\Facades\Schema::hasColumn('app_notifications', 'is_system')) { $payload['is_system'] = true; } $row = DB::transaction(function () use ($customerId, $payload) { $row = AppNotification::create($payload); AppNotificationRecipient::query()->insert([ 'notification_id' => $row->id, 'customer_id' => $customerId, 'created_at' => now(), 'updated_at' => now(), ]); return $row; }); $this->broadcastToCustomer($row, $customerId); return $row; } catch (\Throwable $e) { Log::warning('CustomerAppNotify failed', [ 'customer_id' => $customerId, 'error' => $e->getMessage(), ]); return null; } } private function broadcastToCustomer(AppNotification $row, int $customerId): void { $unread = app(AppNotificationUnreadService::class); $payload = [ 'id' => $row->id, 'title' => $row->title, 'body' => $row->body, 'severity' => $row->severity, 'created_at' => optional($row->created_at)?->toIso8601String(), 'unread_count' => $unread->countForCustomer($customerId), ]; $this->stream->publishForCustomer($customerId, 'app_notification', $payload); $unread->publishForCustomer($customerId); } }