94 lines
3.2 KiB
PHP
94 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Notification;
|
|
|
|
use App\Models\NotificationChannel;
|
|
use Illuminate\Http\Client\ConnectionException;
|
|
use Illuminate\Http\Client\PendingRequest;
|
|
use Illuminate\Http\Client\RequestException;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Validation\ValidationException;
|
|
|
|
class WhapiIdService
|
|
{
|
|
public function state(NotificationChannel $channel): array
|
|
{
|
|
return $this->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;
|
|
}
|
|
}
|