📝 Registrar Persona
Registra aquí a personas que hayas encontrado, rescatado o que estén a salvo. También puedes registrar personas buscadas si conoces su paradero.
🔍 Buscar Persona
Busca en todos los registros por nombre, cédula, estado o municipio.
Ingresa un término de búsqueda para encontrar registros.
🗺️ Registros por Estado
Consulta el listado de personas registradas por cada estado de Venezuela.
📢 Anuncios de Búsqueda
Publica aquí si buscas a alguien y necesitas que el público te ayude a encontrarlo.
Publicar anuncio de búsqueda
Anuncios publicados —
Cargando anuncios…
⚙️ Configuración de Google Sheets
Conecta esta aplicación con una hoja de cálculo de Google Sheets para guardar y leer los datos.
🔗 Instrucciones de configuración
- Crea una hoja de cálculo en Google Drive y compártela públicamente (cualquier persona con el enlace puede ver y editar).
-
Copia el ID de la hoja: es la parte de la URL entre
/d/y/edit.
Ejemplo:https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms/edit - Obtén una API Key de Google: ve a Google Cloud Console, crea un proyecto, activa la API de Google Sheets, y crea una clave de API.
- Crea un Apps Script (Extensiones → Apps Script en tu hoja de cálculo) y configura el Web App como se indica en el README.
- Pega tus datos abajo y haz clic en "Guardar configuración".
📜 Código para Google Apps Script
Copia y pega este código en tu Google Apps Script y despliégalo como Web App:
// =====================================================
// Google Apps Script para SOS Venezuela
// =====================================================
// INSTRUCCIONES:
// 1. Ve a tu hoja de cálculo → Extensiones → Apps Script
// 2. Borra todo el contenido y pega ESTE código completo
// 3. Haz clic en Implementar → Nueva implementación
// - Tipo: Aplicación web
// - Ejecutar como: YO (tu cuenta)
// - Acceso: CUALQUIER PERSONA (incluso anónimos) ← MUY IMPORTANTE
// 4. Copia la URL generada y pégala en el campo "URL del Web App"
// =====================================================
const SHEET_REGISTROS = 'Registros';
const SHEET_ANUNCIOS = 'Anuncios';
const SHEET_COMENTARIOS = 'Comentarios';
// Cabeceras CORS — necesarias para acceso desde el navegador
function corsOutput(body) {
return ContentService
.createTextOutput(body)
.setMimeType(ContentService.MimeType.JSON);
}
// Maneja peticiones OPTIONS (preflight CORS) — algunos navegadores las envían
function doOptions(e) {
return corsOutput('{}');
}
function doPost(e) {
try {
// El cliente envía Content-Type: text/plain para evitar preflight CORS
const data = JSON.parse(e.postData.contents);
const ss = SpreadsheetApp.getActiveSpreadsheet();
if (data.tipo === 'registro') {
const sheet = ss.getSheetByName(SHEET_REGISTROS) || ss.insertSheet(SHEET_REGISTROS);
// Crear encabezados si la hoja está vacía
if (sheet.getLastRow() === 0) {
sheet.appendRow([
'Timestamp','Nombre','Edad','TipoPersn','Genero','Cedula','Telefono',
'Estado','Municipio','Direccion','EstadoSalud','TipoRegistro','DescSalud',
'ReporterNombre','ReporterContacto','Notas','ID'
]);
}
const id = 'R' + Date.now();
sheet.appendRow([
new Date().toISOString(),
data.nombreCompleto || '',
data.edad || '',
data.tipoPersn || '',
data.genero || '',
data.cedula || '',
data.telefono || '',
data.estadoUbic || '',
data.municipio || '',
data.direccion || '',
data.estadoSalud || '',
data.tipoRegistro || '',
data.descripcionSalud|| '',
data.reporterNombre || '',
data.reporterTelefono|| '',
data.notasAdicionales|| '',
id
]);
return corsOutput(JSON.stringify({ ok: true, id }));
}
if (data.tipo === 'anuncio') {
const sheet = ss.getSheetByName(SHEET_ANUNCIOS) || ss.insertSheet(SHEET_ANUNCIOS);
if (sheet.getLastRow() === 0) {
sheet.appendRow([
'Timestamp','NombreBuscado','Edad','Estado',
'Ubicacion','Descripcion','Contacto','NombreReporter','ID'
]);
}
const id = 'A' + Date.now();
sheet.appendRow([
new Date().toISOString(),
data.anuncioNombre || '',
data.anuncioEdad || '',
data.anuncioEstado || '',
data.anuncioUbicacion || '',
data.anuncioDescripcion || '',
data.anuncioContacto || '',
data.anuncioNombreReporter|| '',
id
]);
return corsOutput(JSON.stringify({ ok: true, id }));
}
if (data.tipo === 'comentario') {
const sheet = ss.getSheetByName(SHEET_COMENTARIOS) || ss.insertSheet(SHEET_COMENTARIOS);
if (sheet.getLastRow() === 0) {
sheet.appendRow(['Timestamp','ParentID','Autor','Comentario']);
}
sheet.appendRow([
new Date().toISOString(),
data.parentId || '',
data.autor || '',
data.texto || ''
]);
return corsOutput(JSON.stringify({ ok: true }));
}
return corsOutput(JSON.stringify({ ok: false, error: 'Tipo desconocido: ' + data.tipo }));
} catch (err) {
return corsOutput(JSON.stringify({ ok: false, error: err.message }));
}
}
function doGet(e) {
try {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const tipo = (e.parameter && e.parameter.tipo) || 'registros';
let sheetName = SHEET_REGISTROS;
if (tipo === 'anuncios') sheetName = SHEET_ANUNCIOS;
if (tipo === 'comentarios') sheetName = SHEET_COMENTARIOS;
const sheet = ss.getSheetByName(sheetName);
if (!sheet || sheet.getLastRow() <= 1) {
return corsOutput(JSON.stringify({ ok: true, data: [] }));
}
const rows = sheet.getDataRange().getValues();
const headers = rows[0];
const data = rows.slice(1).map(row => {
const obj = {};
headers.forEach((h, i) => { obj[String(h)] = String(row[i] !== undefined ? row[i] : ''); });
return obj;
});
return corsOutput(JSON.stringify({ ok: true, data }));
} catch (err) {
return corsOutput(JSON.stringify({ ok: false, error: err.message }));
}
}
⚠️ Modo de demostración
Sin configuración guardada, la aplicación funcionará en modo demostración con datos de ejemplo locales. Los registros no se guardarán de forma permanente.