Files
2026-07-14 00:01:48 +03:00

135 lines
4.5 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Http\Controllers\Frontend;
use App\Http\Controllers\Controller;
use App\Models\VoiceCall;
use App\Models\User;
use App\Services\AgoraTokenService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
class VoiceCallController extends Controller
{
public function initiate(Request $request)
{
$request->validate(['callee_id' => 'required|integer|exists:users,id']);
$caller = Auth::user();
$callee = User::findOrFail($request->callee_id);
if ($caller->id === $callee->id) {
return response()->json(['error' => 'Kendinizi arayamazsınız.'], 422);
}
// End any previous active calls
VoiceCall::where('caller_id', $caller->id)
->whereIn('status', ['ringing', 'active'])
->update(['status' => 'ended', 'ended_at' => now()]);
$channelName = 'vc_' . Str::random(20);
$call = VoiceCall::create([
'caller_id' => $caller->id,
'callee_id' => $callee->id,
'channel_name' => $channelName,
'status' => 'ringing',
]);
$callerToken = AgoraTokenService::generateToken($channelName, $caller->id);
$calleeToken = AgoraTokenService::generateToken($channelName, $callee->id);
return response()->json([
'call_id' => $call->id,
'channel_name' => $channelName,
'token' => $callerToken,
'callee' => [
'id' => $callee->id,
'name' => $callee->name,
'avatar' => $callee->avatar ? \App\Support\MediaUrl::fromStoragePath($callee->avatar) : null,
],
'agora_app_id' => env('AGORA_APP_ID', ''),
]);
}
public function answer(VoiceCall $call)
{
$user = Auth::user();
abort_unless($call->callee_id === $user->id, 403);
abort_unless($call->status === 'ringing', 422, 'Call is no longer ringing.');
$call->update(['status' => 'active', 'answered_at' => now()]);
$token = AgoraTokenService::generateToken($call->channel_name, $user->id);
return response()->json([
'channel_name' => $call->channel_name,
'token' => $token,
'agora_app_id' => env('AGORA_APP_ID', ''),
'caller' => [
'id' => $call->caller->id,
'name' => $call->caller->name,
'avatar' => $call->caller->avatar ? \App\Support\MediaUrl::fromStoragePath($call->caller->avatar) : null,
],
]);
}
public function decline(VoiceCall $call)
{
$user = Auth::user();
abort_unless($call->callee_id === $user->id || $call->caller_id === $user->id, 403);
abort_unless($call->status === 'ringing', 422);
$call->update(['status' => 'declined', 'ended_at' => now()]);
return response()->json(['ok' => true]);
}
public function end(VoiceCall $call)
{
$user = Auth::user();
abort_unless($call->callee_id === $user->id || $call->caller_id === $user->id, 403);
$call->update(['status' => 'ended', 'ended_at' => now()]);
return response()->json(['ok' => true]);
}
public function poll(Request $request)
{
$user = Auth::user();
// Check for incoming ringing call
$incoming = VoiceCall::where('callee_id', $user->id)
->where('status', 'ringing')
->with('caller')
->latest()
->first();
if ($incoming) {
return response()->json([
'type' => 'incoming',
'call_id' => $incoming->id,
'caller' => [
'id' => $incoming->caller->id,
'name' => $incoming->caller->name,
'avatar' => $incoming->caller->avatar ? \App\Support\MediaUrl::fromStoragePath($incoming->caller->avatar) : null,
],
]);
}
// Check if an active call we're in has been ended by the other side
$call_id = $request->query('call_id');
if ($call_id) {
$call = VoiceCall::find($call_id);
if ($call && in_array($user->id, [$call->caller_id, $call->callee_id])) {
return response()->json([
'type' => 'status',
'status' => $call->status,
]);
}
}
return response()->json(['type' => 'none']);
}
}