up
This commit is contained in:
@@ -0,0 +1,266 @@
|
||||
<?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()
|
||||
]);
|
||||
}
|
||||
Reference in New Issue
Block a user