From eca0c919a4134979e423bc79a7d51c82bfca601c Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Sun, 25 Jan 2026 21:08:09 -0500 Subject: [PATCH] ip --- api/react_message.php | 34 +++++++++++++++++++++++++++++++++- conversations.php | 6 ++++-- services/WhatsAppService.php | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/api/react_message.php b/api/react_message.php index 469a7e5..dbe7cff 100644 --- a/api/react_message.php +++ b/api/react_message.php @@ -10,9 +10,41 @@ $input = json_decode(file_get_contents('php://input'), true) ?: $_POST; $message_id = $input['message_id'] ?? null; $emoji = $input['emoji'] ?? null; +// Normalize emoji aliases and decode any HTML entities +function normalize_emoji($s) { + if (!$s) return $s; + $orig = $s; + $s = html_entity_decode($s, ENT_QUOTES | ENT_HTML5, 'UTF-8'); + $s_trim = trim(mb_strtolower($s, 'UTF-8')); + $map = [ + 'corazon' => '❤️', 'heart' => '❤️', '<3' => '❤️', + 'like' => '👍', 'thumbsup' => '👍', 'thumbs_up' => '👍', + 'laugh' => '😂', 'risa' => '😂', 'joy' => '😂', + 'wow' => '😮', 'surprised' => '😮', + 'sad' => '😢', 'triste' => '😢', + 'clap' => '👏', 'applause' => '👏', + 'party' => '🎉', 'celebrate' => '🎉', + 'fire' => '🔥', 'pray' => '🙏' + ]; + + $key = preg_replace('/[^a-z0-9_\-]/u', '', $s_trim); + if (isset($map[$key])) return $map[$key]; + + // If it already contains an emoji, extract the first emoji char + if (preg_match('/[\x{1F300}-\x{1F6FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}]/u', $s, $m)) { + return $m[0]; + } + + return trim($orig); +} + +$rawEmoji = $input['emoji'] ?? null; +$emoji = normalize_emoji($emoji); +error_log('react_message: received raw=' . ($rawEmoji ?? 'NULL') . ' normalized=' . ($emoji ?? 'NULL') . ' message_id=' . ($message_id ?? 'NULL')); + if (!$message_id || !$emoji) { http_response_code(400); - echo json_encode(['success' => false, 'error' => 'Parámetros faltantes: message_id, emoji']); + echo json_encode(['success' => false, 'error' => 'Parámetros faltantes: message_id, emoji (después de normalizar)']); exit; } diff --git a/conversations.php b/conversations.php index 73d9233..0d1922c 100644 --- a/conversations.php +++ b/conversations.php @@ -1247,10 +1247,12 @@ const resp = await fetch('api/react_message.php', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({ message_id: mid, emoji: emoji }) }); const j = await resp.json(); if (j && j.success) { + // Prefer the server-side normalized emoji when available (handles alias -> emoji mapping) + const serverEmoji = (j.updated && j.updated.reaction_emoji) ? j.updated.reaction_emoji : emoji; // update local model and UI const m = this.conversations.find(x => x.message_id == mid || x.id == mid); - if (m) m.reaction_emoji = emoji; - this.updateMessageReactionInView && this.updateMessageReactionInView(mid, emoji); + if (m) m.reaction_emoji = serverEmoji; + this.updateMessageReactionInView && this.updateMessageReactionInView(mid, serverEmoji); } else { showAlert && showAlert('Error aplicando reacción', 'danger'); } diff --git a/services/WhatsAppService.php b/services/WhatsAppService.php index 86bae40..fc9c492 100644 --- a/services/WhatsAppService.php +++ b/services/WhatsAppService.php @@ -602,7 +602,38 @@ class WhatsAppService $messageData['reaction_emoji'] = $data['reaction']['emoji'] ?? null; } - $this->db->insert('conversations', $messageData); + // Special handling for reactions: update the referenced message instead of creating a separate outgoing message + if ($data['type'] === 'reaction' && !empty($messageData['reaction_to_message_id'])) { + try { + $targetMid = $messageData['reaction_to_message_id']; + $update = [ + 'reaction_emoji' => $messageData['reaction_emoji'], + 'reaction_to_message_id' => $targetMid, + 'updated_at' => date('Y-m-d H:i:s') + ]; + $this->db->update('conversations', $update, 'message_id = :mid OR id = :mid', ['mid' => $targetMid]); + + // Optionally create a small notification for the operator UI + try { + $this->db->insert('notifications', [ + 'user_id' => $user['id'], + 'type' => 'reaction', + 'message' => 'Reacción: ' . ($messageData['reaction_emoji'] ?? ''), + 'data' => json_encode(['message_id' => $targetMid, 'emoji' => $messageData['reaction_emoji'] ?? '']), + 'is_read' => 0, + 'created_at' => date('Y-m-d H:i:s') + ]); + } catch (Exception $ne) { + error_log('Failed to create reaction notification: ' . $ne->getMessage()); + } + } catch (Exception $e) { + // Fallback: if update fails, insert as outgoing message + error_log('Failed to apply reaction via update, inserting outgoing as fallback: ' . $e->getMessage()); + $this->db->insert('conversations', $messageData); + } + } else { + $this->db->insert('conversations', $messageData); + } // Solo limpiar advisor_requested si el mensaje fue enviado por un asesor (operator) try {