⬑ Total Suscriptores
β
Cargando...
β Activos
β
Cargando...
β Vencidos
β
Cargando...
β Pendiente Skool
β
Cargando...
$ MRR
i
β
Ingreso mensual
ΒΏCΓ³mo se calcula?
Suma de la columna FacturaciΓ³n de todos los suscriptores Activos.
ARR = MRR Γ 12 meses
Suma de la columna FacturaciΓ³n de todos los suscriptores Activos.
ARR = MRR Γ 12 meses
π Churn Rate
i
β
% mensual
ΒΏCΓ³mo se calcula?
Vencidos Γ· (Activos + Vencidos) Γ 100
Representa el % de suscriptores que cancelaron respecto al total con suscripciΓ³n real.
Vencidos Γ· (Activos + Vencidos) Γ 100
Representa el % de suscriptores que cancelaron respecto al total con suscripciΓ³n real.
π Tasa RetenciΓ³n
i
β
% activos reales
ΒΏCΓ³mo se calcula?
100% β Churn Rate
El % de suscriptores que siguen activos vs el total con suscripciΓ³n.
100% β Churn Rate
El % de suscriptores que siguen activos vs el total con suscripciΓ³n.
β
LTV Promedio
i
β
por suscriptor
ΒΏCΓ³mo se calcula?
FacturaciΓ³n total acumulada Γ· total de suscriptores.
CuΓ‘nto ha generado en promedio cada suscriptor desde su primera compra.
FacturaciΓ³n total acumulada Γ· total de suscriptores.
CuΓ‘nto ha generado en promedio cada suscriptor desde su primera compra.
β Compras Prom.
i
β
renovaciones/suscriptor
ΒΏCΓ³mo se calcula?
Suma de "NΓΊmero de Compras" Γ· total suscriptores.
Indica cuΓ‘ntas veces renueva un suscriptor en promedio.
Suma de "NΓΊmero de Compras" Γ· total suscriptores.
Indica cuΓ‘ntas veces renueva un suscriptor en promedio.
Churn vs RetenciΓ³n por Mes
EvoluciΓ³n mensual de cancelaciones vs nuevos
LTV por Plan
Valor total acumulado por tipo de suscripciΓ³n
Suscripciones por Mes
Nuevas vs Cancelaciones + FacturaciΓ³n
Estado Actual
DistribuciΓ³n de status
Por Plan
Por PaΓs
Por Plataforma
FacturaciΓ³n por Plan
Ingresos totales acumulados por tipo de plan
Top PaΓses
FacturaciΓ³n por paΓs
Todos los Suscriptores
β
| Cliente β | Plan β | PaΓs | Plataforma | Status β | Γltima Compra β | RenovaciΓ³n β | FacturaciΓ³n β | Compras |
|---|
π
Acceso restringido
Solo usuarios autorizados pueden gestionar accesos Skool
PrΓ³ximas Renovaciones
Suscripciones con vencimiento en los prΓ³ximos 5 dΓas
| Cliente | Plan | PaΓs | Fecha RenovaciΓ³n | DΓas Restantes | Status | Compras Totales |
|---|
ConfiguraciΓ³n
Conecta tu Google Sheets al dashboard
π Paso a Paso β ConexiΓ³n Google Sheets
Sigue estos pasos para conectar tu Google Sheet como fuente de datos en tiempo real.
1
Abre tu Google Sheet
Ve a Extensiones β Apps Script para abrir el editor de scripts.
2
Crea el script API
Borra el contenido y pega el siguiente cΓ³digo. Este script expone tus datos como una API REST segura.
3
Despliega como Web App
Click en Implementar β Nueva implementaciΓ³n β AplicaciΓ³n web. Acceso: "Cualquier usuario". Copia la URL generada.
4
Pega la URL abajo
Ingresa la URL de tu Apps Script desplegado y guarda. El dashboard se conectarΓ‘ automΓ‘ticamente.
π CΓ³digo Apps Script
Copia y pega este cΓ³digo completo en tu Google Apps Script.
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// SubsTrack β Google Apps Script API v4
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
const SHEET_NAME = 'EstatusClientes';
const LOG_SHEET = 'SkoolRemovals';
// π DOMINIOS PERMITIDOS β solo estas webs pueden usar este script
const ALLOWED_ORIGINS = [
'https://www.aprendamosacademia.com',
'https://aprendamosacademia.com'
];
// ββ Validar origen ββββββββββββββββββββββββββββββββββββββββββ
function isAllowedOrigin(e) {
// JSONP trae el referer como parΓ‘metro 'origin' que aΓ±adimos desde el dashboard
const origin = (e.parameter && e.parameter.origin) || '';
return ALLOWED_ORIGINS.some(allowed => origin.startsWith(allowed));
}
// ββ Rate limiting: mΓ‘x 30 req/min por origen βββββββββββββββ
function checkRateLimit(origin) {
try {
const props = PropertiesService.getScriptProperties();
const key = 'rl_' + origin.replace(/[^a-z0-9]/gi, '_').substring(0, 50);
const now = Date.now();
const raw = props.getProperty(key);
const hits = raw ? JSON.parse(raw).filter(t => now - t < 60000) : [];
if (hits.length >= 30) return false;
hits.push(now);
props.setProperty(key, JSON.stringify(hits));
return true;
} catch(e) { return true; }
}
// ββ Respuesta vacΓa sin pistas ββββββββββββββββββββββββββββββ
function empty(cb) {
const p = JSON.stringify({ success: false });
if (cb) return ContentService.createTextOutput(cb+'('+p+')').setMimeType(ContentService.MimeType.JAVASCRIPT);
return ContentService.createTextOutput(p).setMimeType(ContentService.MimeType.JSON);
}
// ββ doGet βββββββββββββββββββββββββββββββββββββββββββββββββββ
function doGet(e) {
const cb = (e.parameter && e.parameter.callback) || '';
const action = (e.parameter && e.parameter.action) || '';
// π Bloquear si no viene del dominio autorizado
if (!isAllowedOrigin(e)) return empty(cb);
// π Rate limiting
const origin = (e.parameter && e.parameter.origin) || '';
if (!checkRateLimit(origin)) return empty(cb);
// ββ AcciΓ³n: registrar eliminaciΓ³n Skool ββββββββββββββββββ
if (action === 'skoolRemove') {
const email = (e.parameter.email || '').trim().toLowerCase();
if (!email || !email.includes('@') || email.length > 254) return empty(cb);
const ss = SpreadsheetApp.getActiveSpreadsheet();
const mainSheet = ss.getSheetByName(SHEET_NAME);
const mainData = mainSheet.getDataRange().getValues();
const emailCol = mainData[0].indexOf('Email');
// π‘οΈ Solo emails que existan en EstatusClientes
const validEmails = mainData.slice(1).map(r => String(r[emailCol]).trim().toLowerCase());
if (!validEmails.includes(email)) return empty(cb);
let logSheet = ss.getSheetByName(LOG_SHEET);
if (!logSheet) { logSheet = ss.insertSheet(LOG_SHEET); logSheet.appendRow(['Email','Fecha']); }
const existing = logSheet.getDataRange().getValues().flat().map(v => String(v).trim().toLowerCase());
if (!existing.includes(email)) {
const fecha = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'dd/MM/yyyy HH:mm:ss');
logSheet.appendRow([email, fecha]);
}
const r = JSON.stringify({ success: true });
if (cb) return ContentService.createTextOutput(cb+'('+r+')').setMimeType(ContentService.MimeType.JAVASCRIPT);
return ContentService.createTextOutput(r).setMimeType(ContentService.MimeType.JSON);
}
// ββ AcciΓ³n default: devolver datos βββββββββββββββββββββββ
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(SHEET_NAME);
const data = sheet.getDataRange().getValues();
const headers = data[0];
const emailIdx = headers.indexOf('Email');
const SAFE = ['Email','Nombre','Apellido','Pais','PaΓs','Plan','Plataforma',
'Ultima Compra','Γltima Compra','Renovacion','RenovaciΓ³n','Primera Compra',
'Numero de Compras','NΓΊmero de Compras','Status','Estado Skool','ID Subscriptor',
'Facturacion','FacturaciΓ³n'];
const rows = data.slice(1)
.filter(row => { const em = String(row[emailIdx]||'').trim(); return em.includes('@'); })
.map(row => { let o={}; headers.forEach((h,i)=>{ if(SAFE.includes(h)) o[h]=row[i]; }); return o; });
const payload = JSON.stringify({ success: true, data: rows, total: rows.length });
if (cb) return ContentService.createTextOutput(cb+'('+payload+')').setMimeType(ContentService.MimeType.JAVASCRIPT);
return ContentService.createTextOutput(payload).setMimeType(ContentService.MimeType.JSON);
}
β Conectar Dashboard
Una vez desplegado el Apps Script, ingresa la URL aquΓ.
Debe coincidir exactamente con el TOKEN en tu Apps Script
π Embeber en tu Web
Copia este cΓ³digo HTML para embeber el dashboard en cualquier pΓ‘gina web.
<iframe src="URL_DE_TU_DASHBOARD" width="100%" height="800px" frameborder="0" style="border-radius:16px;box-shadow:0 8px 40px rgba(0,0,0,0.3);" ></iframe>