get($channel, '/api/getState'); } public function start(NotificationChannel $channel): array { return $this->get($channel, '/api/serviceStart'); } public function qr(NotificationChannel $channel): array { return $this->get($channel, '/api/getQR'); } public function send(NotificationChannel $channel, string $phone, string $message): array { try { return $this->client($channel)->asForm()->post('/api/sendMessage', [ ...$this->auth($channel), 'phone' => $this->normalizePhone($phone), 'message' => $message, 'forward_type' => 0, 'ephemeral' => 0, ])->throw()->json(); } catch (RequestException|ConnectionException $exception) { $this->providerError($exception); } } private function client(NotificationChannel $channel): PendingRequest { $baseUrl = rtrim((string) data_get($channel->settings, 'base_url'), '/'); if (! $baseUrl || ! preg_match('#^https?://#i', $baseUrl)) { throw ValidationException::withMessages(['base_url' => 'Base URL WHAPI wajib menggunakan HTTP atau HTTPS.']); } $baseUrl = preg_replace('#/api$#i', '', $baseUrl); return Http::baseUrl($baseUrl)->acceptJson()->timeout(30)->retry(2, 500); } private function get(NotificationChannel $channel, string $path): array { try { return $this->client($channel)->get($path, $this->auth($channel))->throw()->json(); } catch (RequestException|ConnectionException $exception) { $this->providerError($exception); } } private function providerError(RequestException|ConnectionException $exception): never { $status = $exception instanceof RequestException ? $exception->response->status() : null; $providerMessage = $exception instanceof RequestException ? data_get($exception->response->json(), 'results.message') ?? data_get($exception->response->json(), 'message') : null; throw ValidationException::withMessages([ 'whapi' => $providerMessage ?: ($status ? "WHAPI merespons HTTP {$status}. Periksa Base URL dan endpoint gateway." : 'Server WHAPI tidak dapat dihubungi.'), ]); } private function auth(NotificationChannel $channel): array { $apiKey = data_get($channel->credentials, 'api_key'); if (! $apiKey) { throw ValidationException::withMessages(['api_key' => 'API Key perangkat WHAPI belum diatur.']); } return ['apiKey' => $apiKey]; } private function normalizePhone(string $phone): string { $phone = preg_replace('/\D+/', '', $phone); if (str_starts_with($phone, '0')) { $phone = '62'.substr($phone, 1); } return $phone; } }