JavaScript de Cero a Experto / APIs del navegador
Clipboard, Geolocation y Notification: APIs con permiso
Copiar al portapapeles, saber dónde está el usuario, mandarle una notificación: tres APIs distintas con UNA cosa en común — tocan la privacidad, así que el navegador exige PERMISO. Hoy aprendes las tres y, más importante, el ritual profesional que comparten: pedir en el momento justo y diseñar para el "no".
La portería del conjunto
Clipboard: copiar con clase
Fíjate en las tres marcas del ritual, que repetirás con toda API sensible:
la acción nace de un GESTO del usuario (el listener del clic — copiar "de
la nada" al cargar está prohibido por el navegador); es ASÍNCRONA con
await (módulo 10: entre tu llamada y el resultado puede mediar una
pregunta al usuario); y el catch tiene un plan B real, no un
console.log de vergüenza. Nota honesta del playground: el iframe del
sandbox restringe algunos permisos — si te cae al plan B aquí, el mismo
código en una página tuya normal copia sin drama (pruébalo en el módulo
17, en tu proyecto).
Geolocation y Notification: mismo ritual, otra puerta
function ubicarUsuario() {
// API de la era de callbacks (módulo 9): éxito y error por separado
navigator.geolocation.getCurrentPosition(
(posicion) => {
const { latitude, longitude } = posicion.coords;
console.log(`Estás cerca de: ${latitude}, ${longitude}`);
},
(error) => {
// el NO llega aquí: la app debe seguir sirviendo
console.log("Sin ubicación (" + error.message + "): usando Bogotá por defecto");
}
);
}
// SIEMPRE desde un botón "usar mi ubicación" — jamás al cargar la páginaasync function activarRecordatorios() {
// el permiso se PIDE explícito y devuelve el veredicto
const veredicto = await Notification.requestPermission();
if (veredicto === "granted") {
new Notification("Mi Bolsillo", {
body: "No olvides registrar tus gastos de hoy 💸",
});
} else {
console.log("Sin notificaciones: mostraremos recordatorios EN la página");
}
}Detalles con historia: Geolocation es de la era pre-promesas — callbacks
de éxito y error por argumentos (¡reconoces el patrón del módulo 9! si
quieres, promisifícala como hiciste con esperar). getCurrentPosition
es una foto; su hermana watchPosition es seguimiento continuo (devuelve
id para cancelar, como setInterval). Y Notification tiene el veredicto
de tres valores: granted, denied, o default (aún no pregunta) — con
denied, NO insistas: el navegador ya ni le muestra la pregunta al
usuario.
La regla de UX que separa apps queridas de apps bloqueadas: pide el permiso en el momento en que el VALOR es obvio. El botón "restaurantes cerca de mí" puede pedir ubicación; la página de inicio pidiendo ubicación + notificaciones + micrófono al aterrizar es la razón de que exista el botón "Bloquear siempre".
Tu app pide permiso de notificaciones apenas carga la página de inicio, antes de que el usuario haga nada. La tasa de 'Bloquear' es altísima y esos usuarios ya no recibirán ni la pregunta. ¿Cuál era el diseño correcto?
Mini-reto
El ritual, en tus manos: 1) en el playground de clipboard, haz que el
texto copiado se construya dinámico (fecha de hoy con Intl + total) en
vez de leer el code; 2) promisifica getCurrentPosition en una función
ubicar() que devuelva promesa (módulo 9, patrón esperar) y úsala con
try/catch + plan B "Bogotá (4.71, -74.07)"; 3) diseña en un comentario
el MOMENTO exacto en que "Mi Bolsillo" pediría cada permiso (¿cuándo tiene
sentido el portapapeles? ¿la ubicación? ¿notificar?). Diseñar el momento
ES la habilidad.
Qué sigue
Última API del tour, y de las que explican el mundo moderno: la History
API — el cuaderno de rutas con el que las SPAs (React, Angular, tu
CodeForge) cambian de "página" sin recargar nada. Cuando entiendas
pushState y popstate, los routers de los frameworks dejarán de ser
magia.