w
This commit is contained in:
@@ -0,0 +1,380 @@
|
||||
<?php
|
||||
/**
|
||||
* Servicio Bot - Manejo de conversaciones y menús
|
||||
* Fecha: 13 de noviembre de 2025
|
||||
*/
|
||||
|
||||
class BotService {
|
||||
private $db;
|
||||
private $whatsappService;
|
||||
|
||||
public function __construct() {
|
||||
$this->db = Database::getInstance();
|
||||
$this->whatsappService = new WhatsAppService();
|
||||
}
|
||||
|
||||
/**
|
||||
* Procesar mensaje entrante
|
||||
*/
|
||||
public function processMessage($user, $messageText, $messageType = 'text') {
|
||||
// Solo procesar mensajes de texto
|
||||
if ($messageType !== 'text') {
|
||||
return;
|
||||
}
|
||||
|
||||
$messageText = trim($messageText);
|
||||
$phoneNumber = $user['phone_number'];
|
||||
|
||||
// Verificar si es un nuevo usuario (enviar mensaje de bienvenida)
|
||||
if ($this->isNewUser($user['id'])) {
|
||||
$this->sendWelcomeMessage($phoneNumber);
|
||||
return;
|
||||
}
|
||||
|
||||
// Procesar comandos especiales
|
||||
if ($this->processSpecialCommands($phoneNumber, $messageText)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Verificar si el usuario está en un menú
|
||||
if ($user['current_menu_id']) {
|
||||
$this->processMenuSelection($user, $messageText);
|
||||
} else {
|
||||
// Procesar respuestas automáticas o comando menu
|
||||
$this->processAutoResponses($phoneNumber, $messageText);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verificar si es un nuevo usuario
|
||||
*/
|
||||
private function isNewUser($userId) {
|
||||
$messageCount = $this->db->fetch(
|
||||
"SELECT COUNT(*) as count FROM conversations WHERE user_id = :user_id",
|
||||
['user_id' => $userId]
|
||||
);
|
||||
|
||||
return $messageCount['count'] <= 1; // Solo el mensaje actual
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviar mensaje de bienvenida
|
||||
*/
|
||||
private function sendWelcomeMessage($phoneNumber) {
|
||||
$welcomeMessage = getConfigFromDB('welcome_message', '¡Hola! 👋 Bienvenido a nuestro servicio automatizado. Escribe *menu* para ver las opciones disponibles.');
|
||||
|
||||
$this->whatsappService->sendTextMessage($phoneNumber, $welcomeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Procesar comandos especiales
|
||||
*/
|
||||
private function processSpecialCommands($phoneNumber, $messageText) {
|
||||
$command = strtolower($messageText);
|
||||
|
||||
switch ($command) {
|
||||
case 'menu':
|
||||
case 'menú':
|
||||
case 'inicio':
|
||||
$this->showMainMenu($phoneNumber);
|
||||
return true;
|
||||
|
||||
case 'salir':
|
||||
case 'exit':
|
||||
case 'cancelar':
|
||||
$this->exitMenu($phoneNumber);
|
||||
return true;
|
||||
|
||||
case 'help':
|
||||
case 'ayuda':
|
||||
$this->showHelp($phoneNumber);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mostrar menú principal
|
||||
*/
|
||||
private function showMainMenu($phoneNumber) {
|
||||
$mainMenu = $this->db->fetch(
|
||||
"SELECT * FROM menus WHERE is_root = 1 AND is_active = 1 ORDER BY order_position LIMIT 1"
|
||||
);
|
||||
|
||||
if ($mainMenu) {
|
||||
$this->showMenu($phoneNumber, $mainMenu['id']);
|
||||
} else {
|
||||
$this->whatsappService->sendTextMessage(
|
||||
$phoneNumber,
|
||||
"❌ No hay menús configurados. Contacta con soporte."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mostrar menú específico
|
||||
*/
|
||||
private function showMenu($phoneNumber, $menuId) {
|
||||
// Obtener información del menú
|
||||
$menu = $this->db->fetch(
|
||||
"SELECT * FROM menus WHERE id = :id AND is_active = 1",
|
||||
['id' => $menuId]
|
||||
);
|
||||
|
||||
if (!$menu) {
|
||||
$this->whatsappService->sendTextMessage(
|
||||
$phoneNumber,
|
||||
"❌ Menú no encontrado."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Obtener opciones del menú
|
||||
$options = $this->db->fetchAll(
|
||||
"SELECT * FROM menu_options WHERE menu_id = :menu_id AND is_active = 1 ORDER BY option_number",
|
||||
['menu_id' => $menuId]
|
||||
);
|
||||
|
||||
if (empty($options)) {
|
||||
$this->whatsappService->sendTextMessage(
|
||||
$phoneNumber,
|
||||
"❌ Este menú no tiene opciones configuradas."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Construir mensaje del menú
|
||||
$menuText = "📋 *" . $menu['title'] . "*\n\n";
|
||||
|
||||
if ($menu['description']) {
|
||||
$menuText .= $menu['description'] . "\n\n";
|
||||
}
|
||||
|
||||
foreach ($options as $option) {
|
||||
$menuText .= $option['option_number'] . ". " . $option['text'] . "\n";
|
||||
}
|
||||
|
||||
$menuText .= "\n💬 *Responde con el número de la opción que deseas*";
|
||||
|
||||
// Actualizar estado del usuario
|
||||
$this->updateUserMenuState($phoneNumber, $menuId);
|
||||
|
||||
// Enviar mensaje
|
||||
$this->whatsappService->sendTextMessage($phoneNumber, $menuText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Procesar selección de menú
|
||||
*/
|
||||
private function processMenuSelection($user, $messageText) {
|
||||
$phoneNumber = $user['phone_number'];
|
||||
$currentMenuId = $user['current_menu_id'];
|
||||
|
||||
// Verificar si es un número
|
||||
if (!is_numeric($messageText)) {
|
||||
$this->whatsappService->sendTextMessage(
|
||||
$phoneNumber,
|
||||
"❌ Por favor, responde solo con el número de la opción deseada."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
$optionNumber = (int)$messageText;
|
||||
|
||||
// Buscar la opción seleccionada
|
||||
$option = $this->db->fetch(
|
||||
"SELECT * FROM menu_options WHERE menu_id = :menu_id AND option_number = :option_number AND is_active = 1",
|
||||
['menu_id' => $currentMenuId, 'option_number' => $optionNumber]
|
||||
);
|
||||
|
||||
if (!$option) {
|
||||
$this->whatsappService->sendTextMessage(
|
||||
$phoneNumber,
|
||||
"❌ Opción inválida. Por favor, selecciona una opción válida del menú."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Procesar acción de la opción
|
||||
$this->processMenuAction($phoneNumber, $option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Procesar acción del menú
|
||||
*/
|
||||
private function processMenuAction($phoneNumber, $option) {
|
||||
switch ($option['action_type']) {
|
||||
case 'menu':
|
||||
// Navegar a otro menú
|
||||
$targetMenu = $this->db->fetch(
|
||||
"SELECT * FROM menus WHERE name = :name AND is_active = 1",
|
||||
['name' => $option['action_value']]
|
||||
);
|
||||
|
||||
if ($targetMenu) {
|
||||
$this->showMenu($phoneNumber, $targetMenu['id']);
|
||||
} else {
|
||||
$this->whatsappService->sendTextMessage(
|
||||
$phoneNumber,
|
||||
"❌ Menú no encontrado: " . $option['action_value']
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'message':
|
||||
// Enviar mensaje de respuesta
|
||||
$this->whatsappService->sendTextMessage($phoneNumber, $option['action_value']);
|
||||
$this->exitMenu($phoneNumber);
|
||||
break;
|
||||
|
||||
case 'api_call':
|
||||
// Llamar API externa (implementar según necesidad)
|
||||
$this->processApiCall($phoneNumber, $option['action_value']);
|
||||
break;
|
||||
|
||||
case 'end':
|
||||
// Finalizar conversación
|
||||
$message = $option['action_value'] ?: "Gracias por usar nuestro servicio. ¡Hasta pronto!";
|
||||
$this->whatsappService->sendTextMessage($phoneNumber, $message);
|
||||
$this->exitMenu($phoneNumber);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Procesar llamada API externa
|
||||
*/
|
||||
private function processApiCall($phoneNumber, $apiEndpoint) {
|
||||
// Aquí puedes implementar llamadas a APIs externas
|
||||
// Por ejemplo, consultar saldos, procesar pagos, etc.
|
||||
$this->whatsappService->sendTextMessage(
|
||||
$phoneNumber,
|
||||
"🔄 Procesando tu solicitud... Un momento por favor."
|
||||
);
|
||||
|
||||
// Simular procesamiento
|
||||
sleep(2);
|
||||
|
||||
$this->whatsappService->sendTextMessage(
|
||||
$phoneNumber,
|
||||
"✅ Tu solicitud ha sido procesada exitosamente."
|
||||
);
|
||||
|
||||
$this->exitMenu($phoneNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Procesar respuestas automáticas
|
||||
*/
|
||||
private function processAutoResponses($phoneNumber, $messageText) {
|
||||
$keyword = strtolower($messageText);
|
||||
|
||||
// Buscar respuesta automática por keyword
|
||||
$autoResponse = $this->db->fetch(
|
||||
"SELECT * FROM auto_responses WHERE trigger_type = 'keyword' AND LOWER(trigger_value) = :keyword AND is_active = 1",
|
||||
['keyword' => $keyword]
|
||||
);
|
||||
|
||||
if ($autoResponse) {
|
||||
$this->whatsappService->sendTextMessage($phoneNumber, $autoResponse['response_text']);
|
||||
|
||||
// Si la keyword es 'menu', mostrar el menú
|
||||
if ($keyword === 'menu' || $keyword === 'menú') {
|
||||
$this->showMainMenu($phoneNumber);
|
||||
}
|
||||
} else {
|
||||
// Respuesta por defecto para mensajes no reconocidos
|
||||
$defaultMessage = "🤖 No entendí tu mensaje. Escribe *menu* para ver las opciones disponibles o *ayuda* para obtener ayuda.";
|
||||
$this->whatsappService->sendTextMessage($phoneNumber, $defaultMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Salir del menú actual
|
||||
*/
|
||||
private function exitMenu($phoneNumber) {
|
||||
$this->db->update(
|
||||
'users',
|
||||
['current_menu_id' => null, 'current_step' => 0, 'session_data' => null],
|
||||
'phone_number = :phone',
|
||||
['phone' => $phoneNumber]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Actualizar estado del menú del usuario
|
||||
*/
|
||||
private function updateUserMenuState($phoneNumber, $menuId) {
|
||||
$this->db->update(
|
||||
'users',
|
||||
['current_menu_id' => $menuId, 'current_step' => 1],
|
||||
'phone_number = :phone',
|
||||
['phone' => $phoneNumber]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mostrar ayuda
|
||||
*/
|
||||
private function showHelp($phoneNumber) {
|
||||
$helpText = "🆘 *Ayuda del Sistema*\n\n";
|
||||
$helpText .= "📋 *menu* - Mostrar menú principal\n";
|
||||
$helpText .= "❌ *salir* - Salir del menú actual\n";
|
||||
$helpText .= "🆘 *ayuda* - Mostrar esta ayuda\n\n";
|
||||
$helpText .= "💡 *Consejos:*\n";
|
||||
$helpText .= "• Responde solo con números en los menús\n";
|
||||
$helpText .= "• Escribe palabras clave para obtener respuestas rápidas\n";
|
||||
$helpText .= "• Si tienes problemas, escribe *soporte*";
|
||||
|
||||
$this->whatsappService->sendTextMessage($phoneNumber, $helpText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Procesar mensaje de soporte
|
||||
*/
|
||||
public function processSupportMessage($phoneNumber, $message) {
|
||||
// Notificar a administradores sobre consulta de soporte
|
||||
$this->whatsappService->sendTextMessage(
|
||||
$phoneNumber,
|
||||
"🆘 Tu mensaje ha sido enviado a nuestro equipo de soporte. Te contactaremos pronto.\n\n" .
|
||||
"📞 También puedes llamarnos al: +57 1 234 5678\n" .
|
||||
"📧 O escribirnos a: soporte@miempresa.com"
|
||||
);
|
||||
|
||||
// Aquí podrías implementar notificaciones a administradores
|
||||
// Por ejemplo, enviar email o notificación a Slack
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener estadísticas del bot
|
||||
*/
|
||||
public function getBotStats() {
|
||||
$stats = [];
|
||||
|
||||
// Total de usuarios
|
||||
$stats['total_users'] = $this->db->fetch(
|
||||
"SELECT COUNT(*) as count FROM users"
|
||||
)['count'];
|
||||
|
||||
// Usuarios activos (último mes)
|
||||
$stats['active_users'] = $this->db->fetch(
|
||||
"SELECT COUNT(DISTINCT user_id) as count FROM conversations
|
||||
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)"
|
||||
)['count'];
|
||||
|
||||
// Total de mensajes
|
||||
$stats['total_messages'] = $this->db->fetch(
|
||||
"SELECT COUNT(*) as count FROM conversations"
|
||||
)['count'];
|
||||
|
||||
// Mensajes hoy
|
||||
$stats['messages_today'] = $this->db->fetch(
|
||||
"SELECT COUNT(*) as count FROM conversations
|
||||
WHERE DATE(created_at) = CURDATE()"
|
||||
)['count'];
|
||||
|
||||
return $stats;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,336 @@
|
||||
<?php
|
||||
/**
|
||||
* Servicio de WhatsApp - Envío de mensajes
|
||||
* Fecha: 13 de noviembre de 2025
|
||||
*/
|
||||
|
||||
class WhatsAppService {
|
||||
private $token;
|
||||
private $phoneNumberId;
|
||||
private $apiUrl;
|
||||
private $db;
|
||||
|
||||
public function __construct() {
|
||||
$this->token = WHATSAPP_TOKEN;
|
||||
$this->phoneNumberId = WHATSAPP_PHONE_NUMBER_ID;
|
||||
$this->apiUrl = WHATSAPP_API_URL;
|
||||
$this->db = Database::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviar mensaje de texto
|
||||
*/
|
||||
public function sendTextMessage($to, $message) {
|
||||
$data = [
|
||||
'messaging_product' => 'whatsapp',
|
||||
'to' => $this->formatPhoneNumber($to),
|
||||
'type' => 'text',
|
||||
'text' => [
|
||||
'body' => $message
|
||||
]
|
||||
];
|
||||
|
||||
return $this->sendMessage($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviar mensaje con template
|
||||
*/
|
||||
public function sendTemplateMessage($to, $templateName, $language = 'es', $parameters = []) {
|
||||
$template = [
|
||||
'name' => $templateName,
|
||||
'language' => [
|
||||
'code' => $language
|
||||
]
|
||||
];
|
||||
|
||||
if (!empty($parameters)) {
|
||||
$template['components'] = [
|
||||
[
|
||||
'type' => 'body',
|
||||
'parameters' => $parameters
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
$data = [
|
||||
'messaging_product' => 'whatsapp',
|
||||
'to' => $this->formatPhoneNumber($to),
|
||||
'type' => 'template',
|
||||
'template' => $template
|
||||
];
|
||||
|
||||
return $this->sendMessage($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviar mensaje con botones interactivos
|
||||
*/
|
||||
public function sendInteractiveMessage($to, $bodyText, $buttons, $header = null, $footer = null) {
|
||||
$interactive = [
|
||||
'type' => 'button',
|
||||
'body' => [
|
||||
'text' => $bodyText
|
||||
],
|
||||
'action' => [
|
||||
'buttons' => $buttons
|
||||
]
|
||||
];
|
||||
|
||||
if ($header) {
|
||||
$interactive['header'] = [
|
||||
'type' => 'text',
|
||||
'text' => $header
|
||||
];
|
||||
}
|
||||
|
||||
if ($footer) {
|
||||
$interactive['footer'] = [
|
||||
'text' => $footer
|
||||
];
|
||||
}
|
||||
|
||||
$data = [
|
||||
'messaging_product' => 'whatsapp',
|
||||
'recipient_type' => 'individual',
|
||||
'to' => $this->formatPhoneNumber($to),
|
||||
'type' => 'interactive',
|
||||
'interactive' => $interactive
|
||||
];
|
||||
|
||||
return $this->sendMessage($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviar mensaje con lista
|
||||
*/
|
||||
public function sendListMessage($to, $bodyText, $buttonText, $sections, $header = null, $footer = null) {
|
||||
$interactive = [
|
||||
'type' => 'list',
|
||||
'body' => [
|
||||
'text' => $bodyText
|
||||
],
|
||||
'action' => [
|
||||
'button' => $buttonText,
|
||||
'sections' => $sections
|
||||
]
|
||||
];
|
||||
|
||||
if ($header) {
|
||||
$interactive['header'] = [
|
||||
'type' => 'text',
|
||||
'text' => $header
|
||||
];
|
||||
}
|
||||
|
||||
if ($footer) {
|
||||
$interactive['footer'] = [
|
||||
'text' => $footer
|
||||
];
|
||||
}
|
||||
|
||||
$data = [
|
||||
'messaging_product' => 'whatsapp',
|
||||
'recipient_type' => 'individual',
|
||||
'to' => $this->formatPhoneNumber($to),
|
||||
'type' => 'interactive',
|
||||
'interactive' => $interactive
|
||||
];
|
||||
|
||||
return $this->sendMessage($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marcar mensaje como leído
|
||||
*/
|
||||
public function markAsRead($messageId) {
|
||||
$data = [
|
||||
'messaging_product' => 'whatsapp',
|
||||
'status' => 'read',
|
||||
'message_id' => $messageId
|
||||
];
|
||||
|
||||
$url = $this->apiUrl . $this->phoneNumberId . '/messages';
|
||||
return $this->makeRequest('POST', $url, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviar mensaje principal
|
||||
*/
|
||||
private function sendMessage($data) {
|
||||
$url = $this->apiUrl . $this->phoneNumberId . '/messages';
|
||||
$response = $this->makeRequest('POST', $url, $data);
|
||||
|
||||
// Guardar mensaje enviado en la base de datos
|
||||
if ($response && isset($response['messages'][0]['id'])) {
|
||||
$this->saveOutgoingMessage($data, $response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Realizar petición HTTP
|
||||
*/
|
||||
private function makeRequest($method, $url, $data = null) {
|
||||
$ch = curl_init();
|
||||
|
||||
$headers = [
|
||||
'Authorization: Bearer ' . $this->token,
|
||||
'Content-Type: application/json',
|
||||
'User-Agent: WhatsApp-Bot/1.0'
|
||||
];
|
||||
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_HTTPHEADER => $headers,
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
CURLOPT_CONNECTTIMEOUT => 10,
|
||||
CURLOPT_SSL_VERIFYPEER => true,
|
||||
CURLOPT_SSL_VERIFYHOST => 2,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_MAXREDIRS => 3
|
||||
]);
|
||||
|
||||
if ($method === 'POST' && $data) {
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
|
||||
}
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($error) {
|
||||
error_log("cURL Error: " . $error);
|
||||
throw new Exception("Error de comunicación con WhatsApp: " . $error);
|
||||
}
|
||||
|
||||
$decoded = json_decode($response, true);
|
||||
|
||||
if ($httpCode >= 400) {
|
||||
$errorMsg = isset($decoded['error']['message']) ? $decoded['error']['message'] : 'Error desconocido';
|
||||
error_log("WhatsApp API Error: " . $response);
|
||||
throw new Exception("Error de WhatsApp API: " . $errorMsg);
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatear número de teléfono
|
||||
*/
|
||||
private function formatPhoneNumber($phone) {
|
||||
// Remover caracteres especiales
|
||||
$phone = preg_replace('/[^0-9]/', '', $phone);
|
||||
|
||||
// Si empieza con +57 (Colombia), mantenerlo
|
||||
if (substr($phone, 0, 2) === '57' && strlen($phone) >= 12) {
|
||||
return $phone;
|
||||
}
|
||||
|
||||
// Si es número colombiano sin código de país
|
||||
if (strlen($phone) === 10 && substr($phone, 0, 1) === '3') {
|
||||
return '57' . $phone;
|
||||
}
|
||||
|
||||
return $phone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guardar mensaje enviado en BD
|
||||
*/
|
||||
private function saveOutgoingMessage($data, $response) {
|
||||
try {
|
||||
$user = $this->getUserByPhone($data['to']);
|
||||
if ($user) {
|
||||
$messageData = [
|
||||
'user_id' => $user['id'],
|
||||
'message_id' => $response['messages'][0]['id'],
|
||||
'direction' => 'outgoing',
|
||||
'message_type' => $data['type'],
|
||||
'content' => $this->extractMessageContent($data),
|
||||
'status' => 'sent',
|
||||
'created_at' => date('Y-m-d H:i:s')
|
||||
];
|
||||
|
||||
$this->db->insert('conversations', $messageData);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log("Error saving outgoing message: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extraer contenido del mensaje para guardar
|
||||
*/
|
||||
private function extractMessageContent($data) {
|
||||
switch ($data['type']) {
|
||||
case 'text':
|
||||
return $data['text']['body'];
|
||||
case 'template':
|
||||
return 'Template: ' . $data['template']['name'];
|
||||
case 'interactive':
|
||||
if (isset($data['interactive']['body']['text'])) {
|
||||
return $data['interactive']['body']['text'];
|
||||
}
|
||||
break;
|
||||
}
|
||||
return json_encode($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener usuario por teléfono
|
||||
*/
|
||||
private function getUserByPhone($phone) {
|
||||
return $this->db->fetch(
|
||||
"SELECT * FROM users WHERE phone_number = :phone",
|
||||
['phone' => $phone]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Descargar archivo multimedia
|
||||
*/
|
||||
public function downloadMedia($mediaId) {
|
||||
$url = $this->apiUrl . $mediaId;
|
||||
|
||||
// Primero obtener información del archivo
|
||||
$mediaInfo = $this->makeRequest('GET', $url);
|
||||
|
||||
if (!$mediaInfo || !isset($mediaInfo['url'])) {
|
||||
throw new Exception("No se pudo obtener información del archivo");
|
||||
}
|
||||
|
||||
// Descargar el archivo
|
||||
$fileUrl = $mediaInfo['url'];
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => $fileUrl,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Authorization: Bearer ' . $this->token
|
||||
],
|
||||
CURLOPT_TIMEOUT => 60,
|
||||
CURLOPT_FOLLOWLOCATION => true
|
||||
]);
|
||||
|
||||
$fileContent = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
if ($httpCode !== 200) {
|
||||
throw new Exception("Error descargando archivo multimedia");
|
||||
}
|
||||
|
||||
return [
|
||||
'content' => $fileContent,
|
||||
'mime_type' => $mediaInfo['mime_type'] ?? 'application/octet-stream',
|
||||
'file_size' => $mediaInfo['file_size'] ?? strlen($fileContent)
|
||||
];
|
||||
}
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user