CRM/backend/app/Services/VoIP/ApiProvider.php

109 خطوط
4.2 KiB
PHP

<?php
namespace App\Services\VoIP;
use App\Models\Setting;
use Illuminate\Support\Facades\Http;
use Throwable;
class ApiProvider implements VoIPProviderInterface
{
public function initiateCall(string $phone, ?string $callerId = null): array
{
$baseUrl = rtrim((string) Setting::where('key', 'voip_api_base_url')->value('value'), '/');
$token = Setting::where('key', 'voip_api_token')->value('value');
$callPath = Setting::where('key', 'voip_api_call_path')->value('value') ?: '/calls';
if (! $baseUrl) {
return [
'success' => false,
'provider_call_id' => null,
'message' => 'نشانی ای‌پی‌آی تماس تنظیم نشده است',
'status' => 'configuration_error',
];
}
$request = Http::acceptJson()->timeout(10);
if ($token) {
$request = $request->withToken($token);
}
$response = $request->post($baseUrl.'/'.ltrim($callPath, '/'), [
'phone' => $phone,
'caller_id' => $callerId,
]);
$body = $response->json() ?: [];
return [
'success' => $response->successful(),
'provider_call_id' => $body['provider_call_id'] ?? $body['call_id'] ?? null,
'message' => $body['message'] ?? ($response->successful() ? 'تماس از راه ای‌پی‌آی ارسال شد' : 'خطا در ارسال تماس از راه ای‌پی‌آی'),
'status' => $body['status'] ?? ($response->successful() ? 'initiated' : 'failed'),
'raw' => $body,
];
}
public function getCallStatus(string $providerCallId): array
{
$baseUrl = rtrim((string) Setting::where('key', 'voip_api_base_url')->value('value'), '/');
$token = Setting::where('key', 'voip_api_token')->value('value');
$statusPath = Setting::where('key', 'voip_api_status_path')->value('value') ?: '/calls/{id}';
if (! $baseUrl) {
return ['status' => 'configuration_error'];
}
$request = Http::acceptJson()->timeout(10);
if ($token) {
$request = $request->withToken($token);
}
$url = $baseUrl.'/'.ltrim(str_replace('{id}', $providerCallId, $statusPath), '/');
$response = $request->get($url);
return $response->json() ?: [
'status' => $response->successful() ? 'unknown' : 'failed',
];
}
public function getRecordingUrl(string $providerCallId): ?string
{
$template = Setting::where('key', 'voip_api_recording_url')->value('value');
return $template ? str_replace('{id}', $providerCallId, $template) : null;
}
public function testConnection(): array
{
$missing = [];
foreach (['voip_api_base_url', 'voip_api_token'] as $key) {
if (! Setting::where('key', $key)->value('value')) {
$missing[] = $key;
}
}
if ($missing !== []) {
return ['ok' => false, 'message' => 'تنظیمات اتصال API کامل نیست.', 'missing' => $missing];
}
$baseUrl = rtrim((string) Setting::where('key', 'voip_api_base_url')->value('value'), '/');
$token = Setting::where('key', 'voip_api_token')->value('value');
$healthPath = Setting::where('key', 'voip_api_health_path')->value('value') ?: '/health';
$started = microtime(true);
try {
$response = Http::acceptJson()->withToken($token)->timeout(10)->get($baseUrl.'/'.ltrim($healthPath, '/'));
$latency = (int) round((microtime(true) - $started) * 1000);
return [
'ok' => $response->successful(),
'message' => $response->successful() ? "اتصال واقعی API موفق بود ({$latency} میلی‌ثانیه)." : "سرویس API پاسخ {$response->status()} داد.",
'missing' => [],
'latency_ms' => $latency,
'http_status' => $response->status(),
];
} catch (Throwable $error) {
return ['ok' => false, 'message' => 'اتصال واقعی API برقرار نشد: '.$error->getMessage(), 'missing' => []];
}
}
}