Files
Sistema-Educativo-Laravel/app/Http/Controllers/WhatsAppChatController.php

128 lines
4.3 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Alumno;
use App\Models\WhatsappLog;
use App\Services\WhatsAppService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class WhatsAppChatController extends Controller
{
public function index()
{
$plantelesIds = Auth::user()->plantelUsuarios->pluck('id');
// Prospectos del plantel que tienen historial de WhatsApp
$prospectos = Alumno::whereHas('alumnos.plantelUsuarios', function ($q) use ($plantelesIds) {
$q->whereIn('plantels.id', $plantelesIds);
})
->whereHas('whatsappLogs')
->with(['alumnos' => fn($q) => $q->select('users.id', 'users.name', 'users.apellidoPaterno', 'users.telefono', 'users.profile_photo_path')])
->get()
->map(function (Alumno $alumno) {
$ultimoMensaje = $alumno->whatsappLogs()->latest('created_at')->first();
$noLeidos = $alumno->whatsappLogs()->where('leido', false)->where('tipo', 'recibido')->count();
return [
'alumno' => $alumno,
'user' => $alumno->alumnos->first(),
'ultimo' => $ultimoMensaje,
'no_leidos' => $noLeidos,
];
})
->sortByDesc(fn($item) => optional($item['ultimo'])->created_at);
$totalNoLeidos = WhatsappLog::whereIn('alumno_id', $prospectos->pluck('alumno.id'))
->where('leido', false)
->where('tipo', 'recibido')
->count();
return view('promocion.chat', compact('prospectos', 'totalNoLeidos'));
}
public function show(Alumno $alumno)
{
$this->autorizarAlumno($alumno);
$logs = WhatsappLog::where('alumno_id', $alumno->id)
->orderBy('created_at')
->get();
// Marcar como leídos
WhatsappLog::where('alumno_id', $alumno->id)
->where('leido', false)
->update(['leido' => true]);
$user = $alumno->alumnos()->first();
return response()->json([
'alumno' => [
'id' => $alumno->id,
'nombre' => $user ? "{$user->name} {$user->apellidoPaterno}" : "Alumno #{$alumno->id}",
'avatar' => $user?->profile_photo_url ?? null,
'tel' => $alumno->telefonoWhatsapp(),
],
'logs' => $logs->map(fn($log) => [
'id' => $log->id,
'tipo' => $log->tipo,
'mensaje' => $log->mensaje,
'media_type' => $log->media_type,
'created_at' => $log->created_at?->format('d/m/Y H:i'),
]),
]);
}
public function send(Request $request, WhatsAppService $whatsapp)
{
$request->validate([
'alumno_id' => 'required|exists:alumnos,id',
'mensaje' => 'required|string|max:4096',
]);
$alumno = Alumno::findOrFail($request->alumno_id);
$this->autorizarAlumno($alumno);
if ($alumno->opt_out) {
return response()->json(['error' => 'El prospecto solicitó no recibir mensajes (opt-out).'], 422);
}
$telefono = $alumno->telefonoWhatsapp();
if (!$telefono) {
return response()->json(['error' => 'El prospecto no tiene teléfono registrado.'], 422);
}
$mensajeId = $whatsapp->enviarTexto($telefono, $request->mensaje);
$log = WhatsappLog::create([
'alumno_id' => $alumno->id,
'telefono' => $telefono,
'tipo' => 'enviado',
'mensaje' => $request->mensaje,
'payload' => ['enviado_por' => Auth::id(), 'whatsapp_id' => $mensajeId],
]);
return response()->json([
'id' => $log->id,
'tipo' => $log->tipo,
'mensaje' => $log->mensaje,
'created_at' => $log->created_at->format('d/m/Y H:i'),
]);
}
private function autorizarAlumno(Alumno $alumno): void
{
$plantelesIds = Auth::user()->plantelUsuarios->pluck('id');
$tiene = $alumno->alumnos()
->whereHas('plantelUsuarios', fn($q) => $q->whereIn('plantels.id', $plantelesIds))
->exists();
if (!$tiene) {
abort(403);
}
}
}