No hay pedidos. Crea el primero con + Nuevo pedido
Estadísticas
📅
Ventas — Último mes
Últimos 30 días
S/ 0.00
Pedidos por estado
Pedidos por mes (últimos 6 meses)
Equipo
👤
Mi Cuenta
Credenciales del administrador actual
Correo electrónico
—
Contraseña
••••••••
Al cambiar contraseña, recibirás un link de restablecimiento en tu correo.
Nombre
Email
Tipo de acceso
Contraseña
Estado
Acciones
👥
No hay usuarios del equipo aún
📧 Marketing Email
💬 Templates de mensajes por segmento
Email
Nombre
Segmento
Días desde compra
Fecha captura
Acciones
📭
No hay emails capturados aún.
Los emails se guardan automáticamente al crear un pedido con Gmail del cliente,
o cuando el cliente lo ingresa en la página de seguimiento.
Configuración
🏆
Logo de la empresa
Aparece en la página de seguimiento de tus clientes
🏢Sube tu logoPNG, JPG, SVG · Recomendado: fondo transparenteClic o arrastra aquí
Datos de la empresa
👆 Comparte este link con tus clientes — solo ingresan su DNI y ven su pedido
📧 Captura de emails en tracking
Activa para mostrar un formulario de email en la página de seguimiento de tus clientes → genera tu lista de marketing
✉️
Mensaje que recibe el cliente
Personaliza el email que se envía automáticamente cuando registras un pedido
Variables disponibles: {{nombre}}Nombre del cliente
{{link}}Link de seguimiento
{{tienda}}Nombre de la tienda
Preview
✉️
Email automático al cliente
⚠️ No configurado
Al guardar un pedido con Gmail, se envía automáticamente el link de seguimiento al cliente.
Requiere cuenta gratis en emailjs.com · Gratis hasta 200 emails/mes
Setup en 3 pasos:
1. Crea cuenta en emailjs.com → Email Services → conecta tu Gmail
2. Email Templates → crea plantilla con variables: {{to_name}}{{link_seguimiento}}{{nombre_tienda}}
3. Copia los IDs y pégalos aquí ↓
📊
Conectar Google Sheets
Sube pedidos desde tu Sheets a TrackPro con un solo clic
⚡ Configuración — solo una vez
1
Abre tu Google Sheets
Ve a Extensiones → Apps Script en el menú superior
2
Pega el código
Borra todo lo que haya, copia el código de abajo y pégalo (Ctrl+V)
3
Escribe tu contraseña
Busca la línea que dice [ESCRIBE AQUI TU CONTRASEÑA DE TRACKPRO] y reemplázala por tu contraseña de TrackPro
4
Guarda y ejecuta
Clic en Guardar (💾) → selecciona la función onOpen → clic en ▶ Ejecutar → Autorizar permisos
✓
¡Listo! Recarga tu Sheets
Aparecerá el menú 🚀 TrackPro arriba. Desde ahí subes todos los pedidos de un clic
🔑 Tus datos — ya incluidos en el código
Empresa ID
—
Email
—
🔒Contraseña: debes escribirla manualmente en el código — busca la línea [ESCRIBE AQUI TU CONTRASEÑA DE TRACKPRO]
Código Apps Script
// =============================================
// TRACKPRO — Script para Google Apps Script
// Sube pedidos de tu Sheets a TrackPro
// =============================================
var EMPRESA_ID = 'TU_EMPRESA_ID';
var FIREBASE_EMAIL = 'TU_EMAIL';
var FIREBASE_PASSWORD = 'TU_PASSWORD';
var FIREBASE_PROJECT = 'empresas-25fc2';
var FIREBASE_API_KEY = 'AIzaSyDLTy_Gp83DPFqelvSA_PgnOHooQY1H4jI';
// ════════════════════════════════════════════
// SUBIR TODO EL SHEET → TRACKPRO
// ════════════════════════════════════════════
function subirATrackPro() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
if (data.length < 2) {
SpreadsheetApp.getUi().alert('La hoja esta vacia.');
return;
}
var primeraFila = data[0].map(function(h){ return String(h||'').toLowerCase(); });
var esTabla = primeraFila.some(function(h){
return h.indexOf('nombre') !== -1 || h.indexOf('dni') !== -1;
});
var pedidos = esTabla ? parsearTabla(data) : parsearFormato(data);
if (pedidos.length === 0) {
SpreadsheetApp.getUi().alert('No se encontraron pedidos validos con DNI.');
return;
}
var ui = SpreadsheetApp.getUi();
var resp = ui.alert('TrackPro', 'Se van a subir ' + pedidos.length + ' pedidos. Continuar?', ui.ButtonSet.YES_NO);
if (resp !== ui.Button.YES) return;
var token;
try { token = getFirebaseToken(); }
catch(e) { ui.alert('Error de login: ' + e.message); return; }
subirFirestore(pedidos, sheet, 2, token);
}
// ════════════════════════════════════════════
// SUBIR SELECCIÓN → TRACKPRO
// ════════════════════════════════════════════
function subirSeleccionATrackPro() {
var sheet = SpreadsheetApp.getActiveSheet();
var sel = sheet.getActiveRange();
var data = sel.getValues();
if (!data || data.length === 0) {
SpreadsheetApp.getUi().alert('No hay celdas seleccionadas.');
return;
}
var primeraFila = data[0].map(function(h){ return String(h||'').toLowerCase(); });
var esTabla = primeraFila.some(function(h){
return h.indexOf('nombre') !== -1 || h.indexOf('dni') !== -1;
});
if (!esTabla) {
var filaInicio = sel.getRow();
if (filaInicio > 1) {
var headersRow = sheet.getRange(filaInicio - 1, sel.getColumn(), 1, sel.getNumColumns()).getValues()[0];
var headersLow = headersRow.map(function(h){ return String(h||'').toLowerCase(); });
if (headersLow.some(function(h){ return h.indexOf('nombre') !== -1 || h.indexOf('dni') !== -1; })) {
data.unshift(headersRow);
esTabla = true;
}
}
}
var pedidos = esTabla ? parsearTabla(data) : parsearFormato(data);
if (pedidos.length === 0) {
SpreadsheetApp.getUi().alert('No se encontraron pedidos validos en la seleccion.');
return;
}
var ui = SpreadsheetApp.getUi();
var resp = ui.alert('TrackPro', 'Se van a subir ' + pedidos.length + ' pedidos de la seleccion. Continuar?', ui.ButtonSet.YES_NO);
if (resp !== ui.Button.YES) return;
var token;
try { token = getFirebaseToken(); }
catch(e) { ui.alert('Error de login: ' + e.message); return; }
subirFirestore(pedidos, sheet, sel.getRow(), token);
}
// ════════════════════════════════════════════
// AUTH FIREBASE
// ════════════════════════════════════════════
function getFirebaseToken() {
var url = 'https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=' + FIREBASE_API_KEY;
var payload = JSON.stringify({ email: FIREBASE_EMAIL, password: FIREBASE_PASSWORD, returnSecureToken: true });
var resp = UrlFetchApp.fetch(url, { method: 'post', contentType: 'application/json', payload: payload, muteHttpExceptions: true });
var data = JSON.parse(resp.getContentText());
if (!data.idToken) throw new Error('Login fallido: ' + (data.error ? data.error.message : 'sin token'));
return data.idToken;
}
// ════════════════════════════════════════════
// PARSERS
// ════════════════════════════════════════════
function buscarColumna(headers, palabras) {
for (var k = 0; k < palabras.length; k++)
for (var i = 0; i < headers.length; i++)
if (headers[i].indexOf(palabras[k]) !== -1) return i;
return -1;
}
function parsearTabla(data) {
var headers = data[0].map(function(h){ return String(h||'').toLowerCase().trim(); });
var cN = buscarColumna(headers, ['nombre','cliente','destinatario']);
var cD = buscarColumna(headers, ['dni','documento']);
var cT = buscarColumna(headers, ['celular','telefono','tel']);
var cP = buscarColumna(headers, ['producto','pedido','items']);
var cM = buscarColumna(headers, ['monto','total','precio','valor']);
var cPr = buscarColumna(headers, ['provincia','region','departamento']);
var cCi = buscarColumna(headers, ['ciudad','distrito']);
var cDi = buscarColumna(headers, ['direccion','address']);
var cO = buscarColumna(headers, ['obs','nota','observ']);
var pedidos = [];
for (var r = 1; r < data.length; r++) {
var row = data[r];
var nom = cN >= 0 ? String(row[cN]||'').trim() : '';
var dni = cD >= 0 ? String(row[cD]||'').replace(/[^0-9]/g,'') : '';
if (!nom || dni.length < 7) continue;
var prods = [];
if (cP >= 0 && row[cP]) {
var pa = String(row[cP]).split(/[,\n|]/);
for (var pp = 0; pp < pa.length; pp++) {
var pt = pa[pp].trim();
if (pt) prods.push(pt);
}
}
var monto = 0;
if (cM >= 0) monto = parseFloat(String(row[cM]||'0').replace(/[^0-9.]/g,'')) || 0;
pedidos.push({
nombre: nom, dni: dni,
telefono: cT >= 0 ? String(row[cT]||'').replace(/[^0-9]/g,'') : '',
productos: prods, monto: monto,
provincia: cPr >= 0 ? String(row[cPr]||'').trim() : '',
ciudad: cCi >= 0 ? String(row[cCi]||'').trim() : '',
direccion: cDi >= 0 ? String(row[cDi]||'').trim() : '',
observaciones: cO >= 0 ? String(row[cO]||'').trim() : '',
estado: 'pendiente'
});
}
return pedidos;
}
function parsearFormato(data) {
var numCols = data[0] ? data[0].length : 2;
var pedidos = [];
var vistos = {};
for (var colL = 0; colL < numCols - 1; colL++) {
var colV = colL + 1;
if (colV >= numCols) continue;
var enc = parsearBloque(data, colL, colV);
for (var fi = 0; fi < enc.length; fi++) {
var p = enc[fi];
var cl = p.dni + '|' + p.nombre;
if (p.dni && p.nombre && !vistos[cl]) {
vistos[cl] = true;
pedidos.push(p);
}
}
}
return pedidos;
}
function parsearBloque(data, colL, colV) {
var result = [];
var curr = null;
var espDest = false;
for (var fi = 0; fi < data.length; fi++) {
var label = String(data[fi][colL]||'').trim();
var value = String(data[fi][colV]||'').trim();
var ll = label.toLowerCase();
if (ll.indexOf('pedido') === 0) {
if (curr && curr.dni) result.push(curr);
curr = { nombre:'', dni:'', telefono:'', provincia:'', ciudad:'', direccion:'', productos:[], monto:0, estado:'pendiente', observaciones:'' };
espDest = false;
if (value) {
var lp = value.split('\n');
for (var l = 0; l < lp.length; l++) {
var ln = lp[l].replace(/^[\u2714\u2713\-\u2022 ]+/, '').trim();
if (ln && !/^(pedido|datos|celular|destino|valor|total|estado)/i.test(ln)) curr.productos.push(ln);
}
}
continue;
}
if (!curr) continue;
if (ll.indexOf('datos del dest') !== -1 && value) {
espDest = false;
var ld = value.split('\n');
for (var l2 = 0; l2 < ld.length; l2++) {
var ln2 = ld[l2];
var md = ln2.match(/dni\s*[:\-]?\s*(\d{7,8})/i);
if (md) curr.dni = md[1];
var mn = ln2.match(/nombres?\s*[:\-]\s*(.+)/i);
if (mn) curr.nombre = mn[1].trim();
var ma = ln2.match(/apellidos?\s*[:\-]\s*(.+)/i);
if (ma && curr.nombre) curr.nombre += ' ' + ma[1].trim();
}
continue;
}
if (/^celular|^tel/i.test(label) && value) { curr.telefono = value.replace(/[^0-9]/g,''); continue; }
if (/^destino/i.test(label)) {
espDest = true;
if (value && !/^agencia$/i.test(value) && value.indexOf('/') !== -1) {
var pt = value.split('/');
curr.provincia = pt[0].trim();
curr.ciudad = pt[pt.length-1].trim();
espDest = false;
}
continue;
}
if (espDest && !label && value) {
espDest = false;
var ldes = value.split('\n');
for (var l3 = 0; l3 < ldes.length; l3++) {
var ln3 = ldes[l3].trim();
if (ln3.indexOf('/') !== -1 && !/shalom/i.test(ln3)) {
var pts = ln3.split('/');
if (pts.length >= 2) { curr.provincia = pts[0].trim(); curr.ciudad = pts[pts.length-1].trim(); }
} else if (ln3 && !/shalom|agencia/i.test(ln3) && !curr.direccion) {
curr.direccion = ln3;
}
}
continue;
}
if (/^valor del prod|^monto|^total/i.test(label) && value) {
var n = parseFloat(value.replace(/[^0-9.]/g,''));
if (n > 0 && curr.monto === 0) curr.monto = n;
continue;
}
if (/^obs/i.test(label) && value) curr.observaciones = value;
}
if (curr && curr.dni) result.push(curr);
return result;
}
// ════════════════════════════════════════════
// SUBIR A FIRESTORE
// ════════════════════════════════════════════
function subirFirestore(pedidos, sheet, filaInicio, token) {
var base = 'https://firestore.googleapis.com/v1/projects/' + FIREBASE_PROJECT + '/databases/(default)/documents/empresas/' + EMPRESA_ID + '/pedidos';
var subidos = 0;
var errores = [];
for (var i = 0; i < pedidos.length; i++) {
var p = pedidos[i];
var vals = [];
for (var vi = 0; vi < p.productos.length; vi++) vals.push({ stringValue: p.productos[vi] });
var docData = {
fields: {
nombre: { stringValue: p.nombre },
dni: { stringValue: p.dni },
telefono: { stringValue: p.telefono },
productos: { arrayValue: { values: vals } },
monto: { doubleValue: p.monto },
provincia: { stringValue: p.provincia },
ciudad: { stringValue: p.ciudad },
direccion: { stringValue: p.direccion },
observaciones: { stringValue: p.observaciones },
estado: { stringValue: p.estado },
tracking: { stringValue: '' },
creadoEn: { timestampValue: new Date().toISOString() },
updatedAt: { timestampValue: new Date().toISOString() }
}
};
try {
var r = UrlFetchApp.fetch(base, {
method: 'post',
contentType: 'application/json',
headers: { 'Authorization': 'Bearer ' + token },
payload: JSON.stringify(docData),
muteHttpExceptions: true
});
var c = r.getResponseCode();
if (c === 200 || c === 201) {
subidos++;
} else {
errores.push('Fila ' + (filaInicio + i) + ': HTTP ' + c);
}
} catch(e) {
errores.push('Fila ' + (filaInicio + i) + ': ' + e.message);
}
if (i > 0 && i % 10 === 0) Utilities.sleep(300);
}
var msg = subidos + ' pedidos subidos a TrackPro.';
if (errores.length) msg += '\n\nErrores (' + errores.length + '):\n' + errores.slice(0,5).join('\n');
SpreadsheetApp.getUi().alert('TrackPro', msg, SpreadsheetApp.getUi().ButtonSet.OK);
}
// ════════════════════════════════════════════
// EXPORTAR (Apps Script como Web App)
// ════════════════════════════════════════════
function doGet(e) {
try {
if (!e.parameter || !e.parameter.data) {
return ContentService.createTextOutput(JSON.stringify({ status: 'TrackPro activo' })).setMimeType(ContentService.MimeType.JSON);
}
var sheet = SpreadsheetApp.getActiveSheet();
var data = JSON.parse(decodeURIComponent(e.parameter.data));
var headers = ['FECHA','NOMBRE','DNI','TELEFONO','PRODUCTOS','MONTO (S/)','PROVINCIA','CIUDAD','DIRECCION','ESTADO','CLAVE SHALOM','OBSERVACIONES'];
if (Array.isArray(data)) {
sheet.clearContents();
sheet.appendRow(headers);
for (var i = 0; i < data.length; i++) {
var p = data[i];
sheet.appendRow([p.fecha||'', p.nombre||'', p.dni||'', p.telefono||'', p.productos||'', p.monto||0, p.provincia||'', p.ciudad||'', p.direccion||'', p.estado||'', p.tracking||'', p.observaciones||'']);
}
} else {
if (sheet.getLastRow() === 0) sheet.appendRow(headers);
sheet.appendRow([data.fecha||'', data.nombre||'', data.dni||'', data.telefono||'', data.productos||'', data.monto||0, data.provincia||'', data.ciudad||'', data.direccion||'', data.estado||'', data.tracking||'', data.observaciones||'']);
}
return ContentService.createTextOutput(JSON.stringify({ ok: true })).setMimeType(ContentService.MimeType.JSON);
} catch(err) {
return ContentService.createTextOutput(JSON.stringify({ ok: false, error: err.toString() })).setMimeType(ContentService.MimeType.JSON);
}
}
// ════════════════════════════════════════════
// MENU
// ════════════════════════════════════════════
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('🚀 TrackPro')
.addItem('Subir TODO el sheet', 'subirATrackPro')
.addItem('Subir SELECCION', 'subirSeleccionATrackPro')
.addToUi();
}
💡
El botón copia el código y abre tu Sheets. Desde ahí ve a
Extensiones → Apps Script, borra lo que haya,
pega con Ctrl+V y escribe tu contraseña donde dice
[ESCRIBE AQUI TU CONTRASEÑA DE TRACKPRO].
📤 EXPORTAR PEDIDOS A TU SHEETS
Pega la URL de tu Apps Script para exportar pedidos de TrackPro a Google Sheets.
Empresas registradas
Empresa
Plan
Pedidos
Usuarios
Estado
Registro
Acciones
🏢
No hay empresas registradas aún
Todos los usuarios
Nombre
Email
Empresa
Rol
Acciones
NUEVA EMPRESA
Gratis
S/ 0/mes
50 pedidos
Básico
S/ 49/mes
500 pedidos
Pro
S/ 99/mes
Ilimitado
NUEVO PEDIDO
📸 Fotos del pedido
📦Foto del paquete empaquetadoHaz clic o arrastra
🚚Screenshot trackingHaz clic o arrastra
🔑Foto clave/datosHaz clic o arrastra
AGREGAR USUARIO
Comparte el email y contraseña para que inicie sesión
🏚️
Empresa no encontrada
No existe ninguna empresa con ese identificador. Verifica el enlace que te compartieron.
🚚
RASTREA TU PEDIDO
Ingresa tu DNI y encuentra tu pedido al instante
SEGUIMIENTO EN TIEMPO REAL
Sin puntos ni espacios · Solo números
Datos seguros
Actualización en tiempo real
Sin registro requerido
🔥
¡Descuentos exclusivos para ti!
Deja tu email y recibe ofertas que no están en la tienda. Solo para clientes que ya compraron.
🎉
¡Tu pedido llegó a la agencia!
Ya está en Shalom, listo para ser despachado hacia ti. ¡Pronto llegará a tus manos! 🚀
Ingresa tu email y te enviaremos un enlace para restablecer tu contraseña.
📦
RASTREA TU PEDIDO
Ingresa los datos para encontrar tu pedido
🤖 IMPORTAR EXCEL CON IA
Sube cualquier Excel con tus pedidos. La IA detecta automáticamente el formato y extrae los datos.
📊
Arrastra tu Excel aquí
o haz clic para seleccionar · .xlsx / .xls
🤖
IA ANALIZANDO TU EXCEL
Leyendo el archivo...
PEDIDOS DETECTADOS
😕
No se pudo analizar el archivo
📋 IMPORTAR DESDE EXCEL (VBA)
📊 CÓMO USAR EN EXCEL
1. Abre tu Excel → Alt + F11 (Editor VBA) 2. Inserta → Módulo → Pega el código de abajo 3. Selecciona las filas con pedidos en tu Excel 4. Ejecuta la macro → se copia el JSON al portapapeles 5. Pega aquí abajo y sube a TrackPro
Sub ExportarPedidosTrackPro()
Dim ws As Worksheet
Dim rng As Range
Dim cell As Range
Dim json As String
Dim rows() As String
Dim i As Integer
Set ws = ActiveSheet
Set rng = Selection
' Detectar columnas automaticamente buscando etiquetas
Dim colDNI As Integer, colNombre As Integer
Dim colTel As Integer, colProd As Integer
Dim colMonto As Integer, colProv As Integer
Dim colCiudad As Integer, colDir As Integer
colDNI = 0: colNombre = 0: colTel = 0
colProd = 0: colMonto = 0: colProv = 0
colCiudad = 0: colDir = 0
' Buscar fila de headers en las primeras 5 filas
Dim headerRow As Integer: headerRow = 0
Dim c As Integer, r As Integer
For r = 1 To 5
For c = 1 To ws.UsedRange.Columns.Count
Dim hdr As String
hdr = LCase(Trim(ws.Cells(r, c).Value))
If hdr = "dni" Or hdr = "documento" Then colDNI = c: headerRow = r
If InStr(hdr, "nombre") > 0 And colNombre = 0 Then colNombre = c
If InStr(hdr, "celular") > 0 Or InStr(hdr, "telefono") > 0 Then colTel = c
If InStr(hdr, "producto") > 0 Then colProd = c
If InStr(hdr, "monto") > 0 Or InStr(hdr, "total") > 0 Then colMonto = c
If InStr(hdr, "provincia") > 0 Or InStr(hdr, "region") > 0 Then colProv = c
If InStr(hdr, "ciudad") > 0 Or InStr(hdr, "distrito") > 0 Then colCiudad = c
If InStr(hdr, "direcc") > 0 Then colDir = c
Next c
If headerRow > 0 Then Exit For
Next r
' Si no hay headers, usar posiciones por defecto comunes
If headerRow = 0 Then
MsgBox "No se encontraron headers (NOMBRE, DNI, etc.)." & Chr(10) & _
"Asegurate que la primera fila tenga los nombres de columnas.", vbExclamation
Exit Sub
End If
json = "["
i = 0
Dim dataRow As Integer
For dataRow = headerRow + 1 To ws.UsedRange.Rows.Count
Dim dni As String, nombre As String
dni = ""
nombre = ""
If colDNI > 0 Then dni = Trim(CStr(ws.Cells(dataRow, colDNI).Value))
If colNombre > 0 Then nombre = Trim(ws.Cells(dataRow, colNombre).Value)
' Solo incluir filas con DNI de 8 digitos y nombre
If Len(dni) = 8 And IsNumeric(dni) And nombre <> "" Then
Dim tel As String, prod As String
Dim monto As String, prov As String
Dim ciudad As String, dir As String
tel = ""
prod = ""
monto = "0"
prov = ""
ciudad = ""
dir = ""
If colTel > 0 Then tel = Trim(CStr(ws.Cells(dataRow, colTel).Value))
If colProd > 0 Then prod = Replace(Trim(ws.Cells(dataRow, colProd).Value), """", "'")
If colMonto > 0 Then
Dim m As Double
m = 0
On Error Resume Next
m = CDbl(ws.Cells(dataRow, colMonto).Value)
On Error GoTo 0
monto = CStr(m)
End If
If colProv > 0 Then prov = Trim(ws.Cells(dataRow, colProv).Value)
If colCiudad > 0 Then ciudad = Trim(ws.Cells(dataRow, colCiudad).Value)
If colDir > 0 Then dir = Replace(Trim(ws.Cells(dataRow, colDir).Value), """", "'")
nombre = Replace(nombre, """", "'")
If i > 0 Then json = json & ","
json = json & Chr(10) & " {"
json = json & """nombre"":""" & nombre & ""","
json = json & """dni"":""" & dni & ""","
json = json & """telefono"":""" & tel & ""","
json = json & """productos"":[""" & prod & """],"
json = json & """monto"":" & monto & ","
json = json & """provincia"":""" & prov & ""","
json = json & """ciudad"":""" & ciudad & ""","
json = json & """direccion"":""" & dir & ""","
json = json & """estado"":""pendiente"","
json = json & """observaciones"":"""""""
json = json & "}"
i = i + 1
End If
Next dataRow
json = json & Chr(10) & "]"
If i = 0 Then
MsgBox "No se encontraron pedidos validos." & Chr(10) & _
"Verifica que haya filas con DNI de 8 digitos.", vbExclamation
Exit Sub
End If
' Copiar al portapapeles
Dim obj As Object
Set obj = CreateObject("Forms.TextBox.1")
obj.MultiLine = True
obj.Text = json
obj.SelectAll
obj.Copy
MsgBox i & " pedidos listos!" & Chr(10) & _
"El JSON fue copiado al portapapeles." & Chr(10) & _
"Pega en TrackPro y sube tus pedidos.", vbInformation, "TrackPro - Exportacion lista"
End Sub
PEDIDOS DETECTADOS
📊 IMPORTAR DESDE GOOGLE SHEETS
Pega el link de tu Google Sheets. La IA lee las filas automáticamente y las sube a tu panel.
📋 Antes de continuar
Tu Google Sheets debe ser público o accesible con el link: Compartir → Cualquier persona con el link → Lector