53 خطوط
2.4 KiB
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]);
|
|
}
|
|
}
|