diff --git a/admin/DashboardController.php b/admin/DashboardController.php
index 817f2a0..5916b42 100644
--- a/admin/DashboardController.php
+++ b/admin/DashboardController.php
@@ -3053,4 +3053,168 @@ HTML;
echo '';
}
}
+
+ // ─── GET /admin/test-message ──────────────────────────────────────────────
+
+ public static function testMessage(): void
+ {
+ SessionAuth::require();
+ $user = SessionAuth::user();
+ $companies = CompanyRepository::all('is_active = 1');
+
+ $opts = '';
+ foreach ($companies as $c) {
+ $opts .= '';
+ }
+
+ echo Layout::open('Mensaje de prueba', 'test', $user['username'] ?? 'Admin');
+ echo <<
+
+
Mensaje de prueba
+
Simula un mensaje entrante de WhatsApp al webhook. El bot responde igual que en producción.
+
+
+
+
+
+
+
+
+HTML;
+ echo Layout::close();
+ }
+
+ // ─── POST /admin/test-message/send ───────────────────────────────────────
+
+ public static function testMessageSend(): void
+ {
+ SessionAuth::require();
+ header('Content-Type: application/json; charset=utf-8');
+
+ $phoneNumberId = trim($_POST['phone_number_id'] ?? '');
+ $fromNumber = preg_replace('/\D/', '', $_POST['from_number'] ?? '');
+ $fromName = trim($_POST['from_name'] ?? 'Test');
+ $message = trim($_POST['message'] ?? '');
+
+ if ($phoneNumberId === '' || $fromNumber === '' || $message === '') {
+ echo json_encode(['ok' => false, 'error' => 'Faltan campos requeridos']);
+ exit;
+ }
+
+ $payload = [
+ 'object' => 'whatsapp_business_account',
+ 'entry' => [[
+ 'id' => 'TEST_WABA',
+ 'changes' => [[
+ 'field' => 'messages',
+ 'value' => [
+ 'messaging_product' => 'whatsapp',
+ 'metadata' => [
+ 'display_phone_number' => '0000000000',
+ 'phone_number_id' => $phoneNumberId,
+ ],
+ 'contacts' => [[
+ 'profile' => ['name' => $fromName],
+ 'wa_id' => $fromNumber,
+ ]],
+ 'messages' => [[
+ 'id' => 'wamid.TEST_' . time(),
+ 'from' => $fromNumber,
+ 'timestamp' => (string)time(),
+ 'type' => 'text',
+ 'text' => ['body' => $message],
+ ]],
+ ],
+ ]],
+ ]],
+ ];
+
+ $json = json_encode($payload, JSON_UNESCAPED_UNICODE);
+ $appSecret = env('WHATSAPP_APP_SECRET', '');
+ $sig = $appSecret !== '' ? 'sha256=' . hash_hmac('sha256', $json, $appSecret) : 'sha256=test';
+
+ // POST al webhook propio vía cURL
+ $webhookUrl = 'https://admin.palmas360.com/admin/v1/wp-webhook';
+ $ch = curl_init($webhookUrl);
+ curl_setopt_array($ch, [
+ CURLOPT_POST => true,
+ CURLOPT_POSTFIELDS => $json,
+ CURLOPT_HTTPHEADER => [
+ 'Content-Type: application/json',
+ 'X-Hub-Signature-256: ' . $sig,
+ ],
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_TIMEOUT => 15,
+ CURLOPT_SSL_VERIFYPEER => false,
+ ]);
+ $resp = curl_exec($ch);
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ $curlErr = curl_error($ch);
+ curl_close($ch);
+
+ if ($curlErr) {
+ echo json_encode(['ok' => false, 'error' => 'cURL: ' . $curlErr]);
+ exit;
+ }
+
+ if ($httpCode === 200) {
+ echo json_encode(['ok' => true, 'message' => 'Mensaje enviado al webhook. Revisa Live Feed y logs.']);
+ } else {
+ $body = is_string($resp) ? substr($resp, 0, 200) : '';
+ echo json_encode(['ok' => false, 'error' => "Webhook respondió HTTP $httpCode. $body"]);
+ }
+ exit;
+ }
}
diff --git a/public/index.php b/public/index.php
index 658610f..afeaf81 100644
--- a/public/index.php
+++ b/public/index.php
@@ -262,6 +262,8 @@ $routes = [
// ─── Procesar cola outbound (protegido o cron) ─────────────────────────
['GET', '/admin/process-queue', fn() => DashboardController::processQueue()],
+ ['GET', '/admin/test-message', fn() => DashboardController::testMessage()],
+ ['POST', '/admin/test-message/send', fn() => DashboardController::testMessageSend()],
// ─── Admin: listar pendientes de aprobación ─────────────────────────────
['GET', '/admin/pending-list', fn() => DashboardController::pendingList()],