| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- <?php
- namespace Services;
- use Libs\Logger;
- class UnipileClient
- {
- private string $dsn;
- private string $apiKey;
- public function __construct()
- {
- $this->dsn = trim((string) ($_ENV['UNIPILE_DSN'] ?? ''));
- $this->apiKey = trim((string) ($_ENV['UNIPILE_API_KEY'] ?? ''));
- }
- public function isConfigured(): bool
- {
- return $this->dsn !== '' && $this->apiKey !== '';
- }
- public function createHostedAuthLink(array $payload): array
- {
- return $this->requestJson('POST', '/hosted/accounts/link', $payload);
- }
- public function sendTextMessage(string $chatId, string $text): array
- {
- return $this->requestMultipart('POST', '/chats/' . rawurlencode($chatId) . '/messages', ['text' => $text]);
- }
- public function apiUrl(): string
- {
- return $this->baseEndpoint();
- }
- private function requestJson(string $method, string $path, array $payload = []): array
- {
- return $this->request($method, $path, [
- 'Content-Type: application/json',
- ], $payload === [] ? '' : json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
- }
- private function requestMultipart(string $method, string $path, array $payload): array
- {
- return $this->request($method, $path, [], $payload);
- }
- private function request(string $method, string $path, array $headers, $body): array
- {
- if (!$this->isConfigured()) {
- throw new \RuntimeException('Unipile is not configured.');
- }
- if (!function_exists('curl_init')) {
- throw new \RuntimeException('PHP cURL extension is required for Unipile requests.');
- }
- $url = $this->baseUrl() . $path;
- $requestHeaders = array_merge([
- 'X-API-KEY: ' . $this->apiKey,
- 'Accept: application/json',
- ], $headers);
- $ch = curl_init($url);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($method));
- curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaders);
- curl_setopt($ch, CURLOPT_TIMEOUT, 30);
- if ($body !== '' && $body !== []) {
- curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
- }
- $raw = curl_exec($ch);
- $error = curl_error($ch);
- $status = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
- curl_close($ch);
- if ($raw === false) {
- Logger::error('Unipile request failed', ['path' => $path, 'error' => $error]);
- throw new \RuntimeException('Unipile request failed.');
- }
- $decoded = json_decode((string) $raw, true);
- if (!is_array($decoded)) {
- $decoded = ['raw' => (string) $raw];
- }
- if ($status < 200 || $status >= 300) {
- Logger::warning('Unipile returned an error', ['path' => $path, 'status' => $status, 'response' => $decoded]);
- throw new \RuntimeException('Unipile returned HTTP ' . $status . '.');
- }
- return $decoded;
- }
- private function baseUrl(): string
- {
- return $this->baseEndpoint() . '/api/v1';
- }
- private function baseEndpoint(): string
- {
- $dsn = preg_replace('#^https?://#', '', $this->dsn) ?? $this->dsn;
- $dsn = rtrim($dsn, '/');
- $dsn = preg_replace('#/api/v1$#', '', $dsn) ?? $dsn;
- return 'https://' . $dsn;
- }
- }
|