Esperanza CRM

Control de prospectos, informes y estatus de inscripciones.

Interesados

0

Inscritos

0

Conversión

0%

Preinscripciones

0
Sin Info 0
Con Informes 0
Visita Agendada 0
Inscritos 🎉 0
En Espera / No Int. 0
Configuración e Integración en la Nube

Respaldos de Datos

Descarga una copia completa de toda la información del CRM para guardarla localmente, o cárgala en caso de cambiar de computadora.

Sincronización en vivo con Google Sheets (Modo Bitácora Histórica)

Introduce tu URL de Google Apps Script. Al sincronizar o guardar cambios, los datos se vaciarán acumulándose al final en un registro cronológico indestructible.

Instrucciones para Sincronizar con Google Sheets (Paso a Paso)
  1. Crea una nueva hoja de cálculo en Google Sheets.
  2. En la primera fila (encabezados de columna), escribe exactamente lo siguiente para que coincidan los datos:
    SyncTimestamp | ID | Alumno | Nivel | Papá/Mamá | Teléfono | Email | Preinscrito | Atendió | Estatus | Notas | FechaActualización
  3. En el menú superior, ve a Extensiones > Apps Script.
  4. Borra todo el código que aparezca y pega el siguiente script ultra-robusto con prevención de duplicados:
    function doPost(e) {
      var payload = JSON.parse(e.postData.contents);
      var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
      
      // Acepta un solo lead o una lista masiva de leads para la sincronización completa
      var items = Array.isArray(payload) ? payload : [payload];
      var timestamp = new Date();
      
      // Obtener los datos actuales de la hoja
      var dataRange = sheet.getDataRange();
      var rows = dataRange.getValues();
      
      // Buscar en qué columna se encuentra el "ID" de manera automática y súper robusta
      var idColumnIndex = -1;
      if (rows.length > 0) {
        var headers = rows[0];
        
        // Método 1: Búsqueda exacta y por palabras clave en los encabezados
        for (var col = 0; col < headers.length; col++) {
          var headerText = headers[col].toString().toUpperCase().trim();
          var words = headerText.split(/[\s_\-]+/);
          
          if (
            headerText === "ID" || 
            headerText === "IDENTIFICADOR" || 
            words.indexOf("ID") !== -1 || 
            words.indexOf("IDENTIFICADOR") !== -1
          ) {
            idColumnIndex = col;
            break;
          }
        }
        
        // Método 2: Heurística por contenido (buscar celdas que comiencen con "lead_")
        if (idColumnIndex === -1 && rows.length > 1) {
          for (var col = 0; col < headers.length; col++) {
            for (var rowIdx = 1; rowIdx < Math.min(rows.length, 10); rowIdx++) {
              var cellValue = rows[rowIdx][col];
              if (cellValue && cellValue.toString().trim().toLowerCase().indexOf("lead_") === 0) {
                idColumnIndex = col;
                break;
              }
            }
            if (idColumnIndex !== -1) break;
          }
        }
      }
      
      // Método 3: Si no se encuentra de ninguna forma, asumimos la columna B (índice 1) por defecto
      if (idColumnIndex === -1) {
        idColumnIndex = 1;
      }
      
      for (var k = 0; k < items.length; k++) {
        var data = items[k];
        var idToFind = data.id.toString().trim();
        
        // Obtener datos frescos actualizados en cada ciclo
        rows = sheet.getDataRange().getValues();
        var rowIndex = -1;
        
        // Buscar si el ID ya existe en la columna correcta (ignorando la cabecera)
        for (var i = 1; i < rows.length; i++) {
          if (rows[i][idColumnIndex] && rows[i][idColumnIndex].toString().trim() === idToFind) {
            rowIndex = i + 1; // Índice de fila basado en 1 para Google Sheets
            break;
          }
        }
        
        var newRow = [
          timestamp,
          data.id,
          data.alumno,
          data.nivel,
          data.padre,
          data.telefono,
          data.email || "",
          data.pagado ? "SÍ" : "NO",
          data.agente,
          data.estatus,
          data.notes || data.notas || "",
          data.fecha
        ];
        
        if (rowIndex > -1) {
          // Si ya existe, sobreescribe esa fila con los datos más recientes (previene duplicados)
          sheet.getRange(rowIndex, 1, 1, newRow.length).setValues([newRow]);
        } else {
          // Si es un lead nuevo, lo agrega al final
          sheet.appendRow(newRow);
        }
      }
      
      return ContentService.createTextOutput(JSON.stringify({result: "success", count: items.length}))
                           .setMimeType(ContentService.MimeType.JSON);
    }
  5. Haz clic en el botón de guardar (icono de disco) e introduce un nombre para el proyecto (ej: "Bitacora Leads").
  6. Haz clic en el botón azul Implementar > Nueva implementación.
  7. En tipo de implementación, selecciona Aplicación web (icono de engranaje).
  8. Configura los campos:
    • Descripción: Bitacora Esperanza CRM
    • Ejecutar como: Yo (tu_correo@gmail.com)
    • Quién tiene acceso: Cualquier persona
  9. Haz clic en Implementar. Otorga los permisos en tu cuenta de Google y copia la **URL de la aplicación web** generada para pegarla en el recuadro de arriba.
  10. ⚠️ ¡CRÍTICO PARA EVITAR DUPLICADOS!
    Cada vez que hagas un cambio en el código de Apps Script o si notas que se siguen repitiendo filas, DEBES CREAR UNA NUEVA VERSIÓN en Google. En la ventana de Apps Script, ve al menú superior Implementar > Gestionar implementaciones, haz clic en el icono de lápiz (Editar), en "Versión" selecciona "Nueva versión", y haz clic en Implementar. Si solo guardas el archivo sin crear una nueva versión, Google seguirá ejecutando la versión vieja que duplicaba los datos.

Registrar Nuevo Interesado

Preinscripción Pagada Desliza para registrar el pago de inscripción
Operación realizada con éxito