Files
whatsapp/api/sync_templates_from_facebook.php
2026-02-03 21:30:55 -05:00

267 lines
10 KiB
PHP

<?php
/**
* API - Sincronizar plantillas desde Facebook/WhatsApp Business API
* Obtiene las plantillas desde la API de WhatsApp y las guarda en la base de datos
*/
require_once '../config/config.php';
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type');
requireAuthentication();
try {
$db = Database::getInstance();
// Obtener configuración de WhatsApp
$token = getConfigFromDB('whatsapp_token', '');
$wabaId = getConfigFromDB('whatsapp_business_account_id', '');
if (empty($token)) {
throw new Exception('Token de WhatsApp no configurado');
}
if (empty($wabaId)) {
throw new Exception('Business Account ID no configurado. Configure el WABA ID en la configuración del sistema.');
}
// Hacer petición a la API de WhatsApp para obtener plantillas
$url = "https://graph.facebook.com/v21.0/{$wabaId}/message_templates";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer {$token}",
"Content-Type: application/json"
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
throw new Exception("Error de conexión: {$error}");
}
if ($httpCode !== 200) {
$errorData = json_decode($response, true);
$errorMsg = $errorData['error']['message'] ?? 'Error desconocido';
throw new Exception("Error de API ({$httpCode}): {$errorMsg}");
}
$data = json_decode($response, true);
// LOG: Ver respuesta completa de WhatsApp
error_log('📥 Respuesta de WhatsApp API: ' . substr($response, 0, 2000));
error_log('📊 Total de plantillas recibidas: ' . count($data['data'] ?? []));
if (!isset($data['data']) || !is_array($data['data'])) {
throw new Exception('Respuesta inválida de la API de WhatsApp');
}
$templates = $data['data'];
// LOG: Ver primera plantilla como ejemplo
if (!empty($templates)) {
error_log('📋 Ejemplo de plantilla recibida: ' . json_encode($templates[0], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
}
$syncedCount = 0;
$updatedCount = 0;
$skippedCount = 0;
$errors = [];
foreach ($templates as $template) {
try {
$templateName = $template['name'] ?? '';
$language = $template['language'] ?? 'es';
$status = $template['status'] ?? 'pending';
$category = $template['category'] ?? 'UTILITY';
$components = $template['components'] ?? [];
if (empty($templateName)) {
$skippedCount++;
continue;
}
// Extraer información de los componentes
$bodyText = null;
$headerText = null;
$headerType = null;
$footerText = null;
$exampleParameters = [];
foreach ($components as $component) {
$type = $component['type'] ?? '';
if ($type === 'BODY') {
$bodyText = $component['text'] ?? null;
// Extraer ejemplos de parámetros del body
if (isset($component['example']['body_text'])) {
$exampleParameters['body'] = $component['example']['body_text'];
}
} elseif ($type === 'HEADER') {
$headerText = $component['text'] ?? null;
$headerType = strtolower($component['format'] ?? 'text');
// Extraer ejemplos del header
if (isset($component['example']['header_text'])) {
$exampleParameters['header'] = $component['example']['header_text'];
}
} elseif ($type === 'FOOTER') {
$footerText = $component['text'] ?? null;
}
}
// NUEVO: Extraer variables automáticamente del body_text
$variables = [];
if ($bodyText) {
// Buscar tanto variables numéricas {{1}} como con nombres {{nombre_tema}}
preg_match_all('/\{\{([^\}]+)\}\}/', $bodyText, $matches);
if (!empty($matches[1])) {
$uniqueVars = array_unique($matches[1]);
error_log("🔍 Template '{$templateName}' - Variables encontradas: " . json_encode($matches[1]));
$index = 1;
foreach ($uniqueVars as $varName) {
$example = null;
// Si la variable es numérica, usar su índice
if (is_numeric($varName)) {
$varIndex = (int)$varName;
// Los ejemplos de WhatsApp vienen como array de arrays: [["valor"]]
if (isset($exampleParameters['body'][$varIndex - 1])) {
$exampleData = $exampleParameters['body'][$varIndex - 1];
$example = is_array($exampleData) ? $exampleData[0] : $exampleData;
}
} else {
// Para variables con nombre, usar índice secuencial
$varIndex = $index;
if (isset($exampleParameters['body'][$index - 1])) {
$exampleData = $exampleParameters['body'][$index - 1];
$example = is_array($exampleData) ? $exampleData[0] : $exampleData;
}
$index++;
}
$variables[] = [
'index' => $varIndex,
'placeholder' => "{{" . $varName . "}}",
'name' => $varName,
'example' => $example
];
}
error_log("✅ Variables procesadas para '{$templateName}': " . json_encode($variables, JSON_UNESCAPED_UNICODE));
}
}
// Si encontramos variables, agregarlas a example_parameters
if (!empty($variables)) {
$exampleParameters['variables'] = $variables;
error_log("💾 example_parameters final para '{$templateName}': " . json_encode($exampleParameters, JSON_UNESCAPED_UNICODE));
}
// Preparar datos para guardar
$componentsJson = !empty($components) ? json_encode($components, JSON_UNESCAPED_UNICODE) : null;
$exampleJson = !empty($exampleParameters) ? json_encode($exampleParameters, JSON_UNESCAPED_UNICODE) : null;
// Verificar si la plantilla ya existe
$existing = $db->fetch(
"SELECT id, status FROM message_templates WHERE template_name = ? AND language_code = ?",
[$templateName, $language]
);
if ($existing) {
// Actualizar plantilla existente con nuevos campos
$db->execute(
"UPDATE message_templates SET
status = ?,
category = ?,
body_text = ?,
header_text = ?,
header_type = ?,
footer_text = ?,
components = ?,
example_parameters = ?,
updated_at = NOW()
WHERE id = ?",
[
strtolower($status),
strtolower($category),
$bodyText,
$headerText,
$headerType,
$footerText,
$componentsJson,
$exampleJson,
$existing['id']
]
);
$updatedCount++;
} else {
// Insertar nueva plantilla con componentes
$db->execute(
"INSERT INTO message_templates (
name,
template_name,
language_code,
category,
status,
body_text,
header_text,
header_type,
footer_text,
components,
example_parameters,
created_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())",
[
$templateName, // nombre descriptivo igual al nombre técnico
$templateName,
$language,
strtolower($category),
strtolower($status),
$bodyText,
$headerText,
$headerType,
$footerText,
$componentsJson,
$exampleJson
]
);
$syncedCount++;
}
} catch (Exception $e) {
$errors[] = "Error procesando plantilla '{$templateName}': " . $e->getMessage();
}
}
// Log de la sincronización
writeLog('INFO', "Plantillas sincronizadas desde Facebook: {$syncedCount} nuevas, {$updatedCount} actualizadas, {$skippedCount} sin cambios");
echo json_encode([
'success' => true,
'message' => 'Plantillas sincronizadas correctamente',
'data' => [
'total' => count($templates),
'synced' => $syncedCount,
'updated' => $updatedCount,
'skipped' => $skippedCount,
'errors' => $errors
]
]);
} catch (Exception $e) {
error_log("Error in sync_templates_from_facebook.php: " . $e->getMessage());
http_response_code(500);
echo json_encode([
'success' => false,
'error' => $e->getMessage()
]);
}