Capítulo nube de la guía Neblla — guardar ficheros en el Google Drive o el Dropbox de una persona, o en los tuyos. El contrato base está en core.txt; el criterio de cuándo usar Neblla, en empezar.txt.

Guardar en tu nube (neblla.cloud)

Módulo opcional cloud (se enciende en el panel o con neblla_update_app). Una app guarda un fichero (un vídeo, un PDF, una foto original) en el Google Drive o el Dropbox de quien la usa, o en los del developer. Los bytes no pasan por Neblla: van del navegador al proveedor (Google), o del navegador a un almacén temporal de Neblla desde el que Dropbox lo recoge y se borra (Dropbox). Neblla solo concede el permiso y comprueba el resultado.

Para qué sirve (y qué no)

Dos dueños

1. La nube de la persona (to: 'mine', por defecto). La persona la enlaza con una ventana de Neblla y decide por app. La app nunca ve un token. Sin Login de Neblla es un enlace «solo esta vez» (dura una hora, no se recuerda nada). 2. La nube del developer (to: 'app'). La conecta el developer en Conexiones › «Tu nube» (o neblla_projects connect_cloud, que da el enlace del panel: nunca se escribe un token). Un servidor real (propio o en la nube) siempre puede usarla; un cliente de jugador, y un Fog (que es un dispositivo de jugador), solo si el developer lo permite con neblla_projects cloud_settings (fromClient, por defecto no), por defecto solo con Login (loggedInOnly), y con límites por fichero y por usuario y día.

Uso


// Desde un clic (abre una ventana):
const { email } = await neblla.cloud.connect('google');        // o 'dropbox'
const up = neblla.cloud.put('google', blobOFile, { name: 'viaje.mp4', folder: 'vacaciones' })
  .on('progress', ({ sent, total }) => bar.value = sent / total);
const r = await up;            // { provider, id, name, size, verified, link? | path? }
// up.abort() lo cancela.

neblla.cloud.providers();      // [{ id, name, available, linked: { email, remembered } | null }]
neblla.cloud.disconnect('google');

// En la nube del developer (también desde room.js en un servidor real):
await neblla.cloud.putToApp(bytes, { name: 'consentimiento-ana.pdf', folder: 'clientes/ana' });

source: un Blob/File, un ArrayBuffer/Uint8Array, un ReadableStream (con size) o una URL. folder: hasta tres niveles, sin ... La carpeta de la app es siempre la del que llama: una app no puede escribir en la de otra.

Recetas

«Guardar en mi Drive» junto a una descarga privada (fotos, partituras, un ebook que la persona compró). media.download da un enlace firmado de 5 minutos y put acepta una URL: el fichero va del almacén al Drive de la persona sin pasar por tu app ni por Neblla.


saveBtn.onclick = async () => {
  const d = await neblla.media.download(mediaId);              // { url, name, mime, bytes } (CLIENT, login)
  await neblla.cloud.connect('google');                        // solo si aún no está enlazado
  const r = await neblla.cloud.put('google', d.url, { name: d.name, mime: d.mime, folder: 'compras' });
  status.textContent = r.link ? 'Guardado: ' + r.link : 'Guardado';
};

El almacén del original debe dejar leer el enlace firmado desde la web de tu app (CORS GET); si no, put falla con source_unreachable. Para un fichero que no cabe en memoria, deja que el navegador haga el fetch y pasa el cuerpo como ReadableStream con size.

Una app que recoge documentos en el Drive del developer (consentimientos, informes, currículos). La persona no necesita cuenta de nube: tú conectas la tuya una vez en Conexiones > «Tu nube» (o con neblla_projects) y apuntas cada fichero a to: 'app':


// Cliente (hay que marcar «dejar que los usuarios de esta app guarden aquí»; con login por defecto):
const r = await neblla.cloud.putToApp(file, { name: `cv-${Date.now()}.pdf`, folder: 'candidaturas' });
// Servidor real (room.js en tu host): siempre permitido, sin ese permiso.
await neblla.cloud.putToApp(bytes, { name: 'informe.pdf', folder: 'informes/' + mes });

La carpeta es Neblla/<tu app>/… en tu Drive; la persona nunca ve tu nube y los límites diarios (fileBytes, perUserDayBytes, appDayBytes) protegen tu espacio.

Integridad

El SDK calcula el SHA-256 (Google) o el content_hash de bloques de 4 MB (Dropbox) mientras sube y lo compara con el que dice el proveedor. Si no cuadra, Neblla borra la copia y el put falla con cloud_checksum_mismatch. Si Google aún no da el hash, el put termina con verified: false (la copia se queda).

Errores

cloud_not_linked · cloud_consent_required (la persona no ha permitido a *esta* app) · cloud_relink (el proveedor cortó el enlace: volver a conectar) · cloud_quota (su Drive/Dropbox está lleno) · cloud_checksum_mismatch · cloud_busy (3 subidas a la vez por conexión) · file_too_large · invalid_file · invalid_folder · provider_unavailable · cloud_dev_not_connected · cloud_from_client_off · login_required · cloud_limit_user · cloud_limit_app · cloud_session_expired · cancelled (la ventana se cerró) · popup_blocked · feature_disabled (módulo cloud apagado).

Privacidad

La app nunca recibe un token de la persona ni del developer; los tokens de larga duración se guardan sellados y el enlace de la persona se ve y se quita en su cuenta › Permisos › «Tus nubes». Google solo da acceso a los ficheros que Neblla crea (drive.file); Dropbox, a la carpeta Apps/Neblla.