diff --git a/api/send_broadcast.php b/api/send_broadcast.php index 6af18ab..80c298b 100644 --- a/api/send_broadcast.php +++ b/api/send_broadcast.php @@ -168,11 +168,22 @@ try { throw new Exception("La plantilla requiere {$expectedVars} variable(s) numéricas, pero se enviaron " . count($processedVariables)); } + // Preparar header de imagen dinámica si se proporcionó + $headerParams = []; + if (!empty($input['header_image_url'])) { + $imageUrl = filter_var($input['header_image_url'], FILTER_VALIDATE_URL) ? $input['header_image_url'] : null; + if ($imageUrl) { + $headerParams = [['type' => 'image', 'image' => ['link' => $imageUrl]]]; + error_log("Broadcast template header image URL: " . $imageUrl); + } + } + $response = $whatsappService->sendTemplateMessage( $user['phone_number'], $template['template_name'] ?? $template['name'], $template['language_code'] ?? 'es', - $processedVariables + $processedVariables, + $headerParams ); // Construir contenido para BD (reemplazar variables en body_text) diff --git a/api/send_message.php b/api/send_message.php index 2c4da67..27b9180 100644 --- a/api/send_message.php +++ b/api/send_message.php @@ -260,9 +260,19 @@ try { error_log("Method: sendTemplateMessage()"); error_log("========================================================"); + // Preparar header de imagen dinámica si se proporcionó + $headerParams = []; + if (!empty($input['header_image_url'])) { + $imageUrl = filter_var($input['header_image_url'], FILTER_VALIDATE_URL) ? $input['header_image_url'] : null; + if ($imageUrl) { + $headerParams = [['type' => 'image', 'image' => ['link' => $imageUrl]]]; + error_log("Template header image URL: " . $imageUrl); + } + } + // Intentar envío y, si falla por traducción no encontrada, probar variantes de idioma try { - $response = $whatsappService->sendTemplateMessage($recipient, $template, $language, $parameters, [], $componentsSimple); + $response = $whatsappService->sendTemplateMessage($recipient, $template, $language, $parameters, $headerParams, $componentsSimple); } catch (Exception $e) { $message = $e->getMessage(); diff --git a/assets/js/app_simple.js b/assets/js/app_simple.js index cbd876c..b95b1cf 100644 --- a/assets/js/app_simple.js +++ b/assets/js/app_simple.js @@ -1558,11 +1558,25 @@ class SimpleWhatsAppManager { } } + // Subir imagen de header si el usuario seleccionó una + let headerImageUrl = null; + const msgImgInput = document.getElementById('message-template-image'); + if (msgImgInput && msgImgInput.files && msgImgInput.files[0]) { + try { + this.showInfo('Subiendo imagen de la plantilla...'); + headerImageUrl = await this._uploadTemplateImage(msgImgInput); + } catch (e) { + this.showError('Error subiendo imagen de la plantilla: ' + e.message); + return; + } + } + messageData = { recipient: recipient, type: 'template', template_name: templateName, // Usar template_name en lugar de ID - parameters: tplParams + parameters: tplParams, + ...(headerImageUrl ? { header_image_url: headerImageUrl } : {}) }; } @@ -1935,6 +1949,18 @@ class SimpleWhatsAppManager { return; } + // Subir imagen de header broadcast si existe + const bcImgInput = document.getElementById('broadcast-template-image'); + if (bcImgInput && bcImgInput.files && bcImgInput.files[0]) { + try { + this.showInfo('Subiendo imagen de la plantilla...'); + payload.header_image_url = await this._uploadTemplateImage(bcImgInput); + } catch (e) { + this.showError('Error subiendo imagen de la plantilla: ' + e.message); + return; + } + } + try { this.showInfo('Enviando mensajes masivos...'); const result = await this.apiCall('send_broadcast.php', { @@ -1956,6 +1982,19 @@ class SimpleWhatsAppManager { } } + // Sube una imagen al servidor y retorna la URL pública + async _uploadTemplateImage(fileInput) { + const file = fileInput.files[0]; + if (!file) return null; + const fd = new FormData(); + fd.append('file', file); + const resp = await fetch('./api/upload_media.php', { method: 'POST', body: fd }); + if (!resp.ok) throw new Error(`HTTP ${resp.status}`); + const data = await resp.json(); + if (data.success && data.public_url) return data.public_url; + throw new Error(data.error || 'No se pudo subir la imagen'); + } + // Gestión de usuarios centralizada en lab_usuarios.php async loadAdminUsers() { // No-op: la UI redirige a lab_usuarios.php @@ -3184,22 +3223,53 @@ window.loadMessageTemplateDetails = async function() { console.log('📋 Variables:', template.variables); const variablesContainer = document.getElementById('message-template-variables'); - + + // Detectar header de imagen + const hasImageHeader = (template.header_type || '').toUpperCase() === 'IMAGE'; + let html = ''; + + if (hasImageHeader) { + html += ` +
Esta plantilla requiere una imagen de encabezado dinámica. Súbela aquí.
+ + +Esta plantilla no tiene variables
'; - variablesContainer.style.display = 'block'; + if (!hasImageHeader) html += 'Esta plantilla no tiene variables de texto
'; + console.log('⚠️ Template sin variables de texto'); + variablesContainer.innerHTML = html; + variablesContainer.style.display = (hasImageHeader || html) ? 'block' : 'none'; } updateMessagePreview(); diff --git a/index.php b/index.php index 17e2833..935bf9d 100644 --- a/index.php +++ b/index.php @@ -1977,22 +1977,53 @@ try { console.log('📋 Variables:', template.variables); const variablesContainer = document.getElementById('broadcast-template-variables'); - + + // Detectar header de imagen + const hasImageHeader = (template.header_type || '').toUpperCase() === 'IMAGE'; + let html = ''; + + if (hasImageHeader) { + html += ` +Esta plantilla requiere una imagen de encabezado dinámica. Súbela aquí.
+ + +Esta plantilla no tiene variables de texto
'; console.log('⚠️ Template sin variables'); - variablesContainer.innerHTML = 'Esta plantilla no tiene variables
'; - variablesContainer.style.display = 'block'; + variablesContainer.innerHTML = html; + variablesContainer.style.display = (hasImageHeader || html) ? 'block' : 'none'; } updateBroadcastPreview();