Files
fernando f246a709c4 feat: WhatsApp webhook — reescritura del controller y rutas en web.php
Simplifica WhatsAppWebhookController: messages crea WhatsappLog con tipo
'recibido', statuses actualiza el log existente por whatsapp_mensaje_id,
opt-out detecta solo STOP/cancelar con regex. Agrega rutas GET/POST
/webhook/whatsapp fuera del grupo auth en web.php (POST sin CSRF).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 22:01:37 -06:00

62 lines
1.9 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\WhatsappLog;
use App\Services\WhatsAppService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class WhatsAppWebhookController extends Controller
{
public function verify(Request $request): Response
{
$verifyToken = config('services.whatsapp.verify_token');
if (
$request->query('hub_mode') === 'subscribe' &&
$request->query('hub_verify_token') === $verifyToken
) {
return response($request->query('hub_challenge'), 200);
}
return response('Forbidden', 403);
}
public function handle(Request $request, WhatsAppService $whatsapp): JsonResponse
{
$payload = $request->all();
$value = data_get($payload, 'entry.0.changes.0.value', []);
$messages = data_get($value, 'messages', []);
$statuses = data_get($value, 'statuses', []);
foreach ($messages as $message) {
$telefono = data_get($message, 'from');
$texto = data_get($message, 'text.body', '');
WhatsappLog::create([
'telefono' => $telefono,
'tipo' => 'recibido',
'mensaje' => $texto,
'whatsapp_mensaje_id' => data_get($message, 'id'),
'payload' => $payload,
]);
if (preg_match('/\b(STOP|cancelar)\b/i', $texto)) {
$whatsapp->procesarOptOut($telefono);
}
}
foreach ($statuses as $status) {
$mensajeId = data_get($status, 'id');
$statusEnvio = data_get($status, 'status');
WhatsappLog::where('whatsapp_mensaje_id', $mensajeId)
->update(['status_envio' => $statusEnvio]);
}
return response()->json(['status' => 'ok']);
}
}