CRM/backend/app/Http/Controllers/Api/VoipWebhookController.php

53 خطوط
2.4 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Call;
use App\Models\CallLog;
use App\Models\Setting;
use App\Services\ActivityLogger;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class VoipWebhookController extends Controller
{
public function __invoke(Request $request): JsonResponse
{
$secret = (string) Setting::where('key', 'voip_webhook_secret')->value('value');
abort_if($secret === '', 503, 'Webhook تلفن پیکربندی نشده است.');
$signature = (string) $request->header('X-VoIP-Signature');
$expected = hash_hmac('sha256', $request->getContent(), $secret);
abort_unless($signature !== '' && hash_equals($expected, $signature), 401, 'امضای Webhook معتبر نیست.');
$validated = $request->validate([
'provider_call_id' => 'required|string|max:255',
'status' => 'required|in:initiated,ringing,answered,completed,failed,busy,no_answer,cancelled',
'duration_seconds' => 'nullable|integer|min:0|max:86400',
'recording_url' => 'nullable|url|max:2048',
'result' => 'nullable|string|max:50',
'started_at' => 'nullable|date',
'ended_at' => 'nullable|date',
]);
$call = Call::where('provider_call_id', $validated['provider_call_id'])->firstOrFail();
$terminal = in_array($validated['status'], ['completed', 'failed', 'busy', 'no_answer', 'cancelled'], true);
$call->update([
'provider_status' => $validated['status'],
'duration' => $validated['duration_seconds'] ?? $call->duration,
'recording_url' => $validated['recording_url'] ?? $call->recording_url,
'result' => $validated['result'] ?? $call->result,
'started_at' => $validated['started_at'] ?? $call->started_at,
'ended_at' => $validated['ended_at'] ?? ($terminal ? now() : $call->ended_at),
'provider_payload' => $request->all(),
]);
CallLog::where('call_id', $call->id)->update([
'recording_url' => $call->recording_url,
'result' => $call->result,
]);
ActivityLogger::log('voip_webhook_received', "VoIP status {$validated['status']} received for call {$call->id}", $call, null, ['provider_call_id' => $call->provider_call_id]);
return response()->json(['ok' => true, 'call_id' => $call->id]);
}
}