Ray-Ban Meta + Odoo: de un vistazo a una tarea

Unas gafas inteligentes sin pantalla, una PWA de compartir y un pequeño webhook en Odoo

Las gafas Ray-Ban Meta a la izquierda, una flecha con la etiqueta compartir hacia webhook, y a la derecha una tarjeta de tarea de Odoo titulada Capturas Gafas, con la etiqueta LTC Labs

Estás delante de un cuadro eléctrico, con las dos manos ocupadas, y quieres que una foto quede registrada como una tarea en Odoo antes de marcharte.

Sin sacar el móvil del bolsillo, sin abrir ninguna app, sin rellenar después un formulario de memoria. Solo mirar, capturar y seguir trabajando. Ese era el encargo de esta sesión, y la herramienta para el trabajo eran unas gafas Ray-Ban Meta.

Las gafas son estupendas en la parte de capturar. Hacen una foto, un clip de vídeo o una nota de voz en el momento en que tocas la patilla o lo dices en voz alta. Lo difícil es todo lo que pasa después del disparo: sacar ese contenido del móvil y llevarlo al sitio correcto de nuestro ERP, sin que acabe en un montón de archivos que nadie ordena nunca.

La restricción que lo condicionó todo

Usamos el modelo de Ray-Ban Meta sin pantalla, y conviene ser sincero sobre lo que eso implica: estas gafas no exponen ninguna API para desarrolladores. No hay SDK con el que enviar una foto a un servidor, ni webhook al que las gafas puedan llamar. El contenido aterriza en la galería de tu móvil a través de la app complementaria de Meta, y ese es el único asidero que tienes.

Así que la integración no podía empezar en las gafas. Tenía que empezar en el móvil, en el momento exacto en que decides que una captura merece la pena guardar. En Android, ese momento tiene nombre: el menú de compartir.

Una PWA que vive en el menú de compartir

La respuesta es una pequeña Progressive Web App construida en torno a la API Web Share Target. Una vez instalada, se registra como destino en el menú de compartir de Android, justo al lado de las apps de mensajería y correo. Abres la captura en la galería, pulsas compartir y eliges nuestra app.

Lo que ocurre a continuación es deliberadamente aburrido, porque lo aburrido es fiable. Un service worker intercepta los archivos compartidos, los guarda en el almacenamiento local del navegador y abre una pantalla de revisión. Ahí ves la foto o reproduces el clip, escribes un título corto y una descripción opcional, y pulsas un botón. La app sube todo a Odoo y te muestra el número de tarea que acaba de crear.

Todo el front end son tres archivos pequeños: un manifiesto que declara el destino de compartir, un service worker que captura la subida y un par de páginas HTML. Sin framework, sin paso de compilación. Se sirve como archivos estáticos sin más desde nginx, lo que significa que no hay nada extra que mantener en marcha y muy poco que pueda romperse en la capa web.

El lado de Odoo: un webhook, una tarea

En el lado de Odoo vive un módulo diminuto llamado glasses_capture. Añade un único endpoint HTTP que acepta los archivos subidos junto con el título y la descripción, y crea una tarea en un proyecto llamado Capturas Gafas, con cada archivo adjunto. Ese es todo su cometido: convertir una subida multipart en una tarea que puedas clasificar más tarde desde tu escritorio.

Un par de pequeños detalles hacen que el resultado sea agradable de usar. El nombre de la tarea se prefija automáticamente con una etiqueta por cada tipo de contenido que lleva, de modo que una subida mixta se lee de un vistazo como [photo][video] obra. Si lo compartido incluía datos de ubicación, se añaden a la descripción. El endpoint está protegido por un token bearer, así que no cualquiera puede colar tareas en el ERP.

Diagrama de la canalización en cinco pasos: las gafas Ray-Ban Meta, la app de Meta y la galería del móvil, la PWA de destino de compartir, un POST al endpoint de captura protegido por un token bearer, y una tarea de Odoo en el proyecto Capturas Gafas

La trampa del multibase de datos

El error más interesante nunca llegó al usuario, porque apareció la primera vez que apuntamos la PWA al servidor real. El webhook funcionaba perfectamente en las pruebas y devolvía un escueto 404 en producción. La diferencia: producción sirve varias bases de datos detrás de un mismo Odoo, y una ruta en un servidor multibase de datos solo es alcanzable antes de elegir base de datos si el controlador se declara público y el módulo se carga a nivel de servidor.

Dicho de otro modo, un webhook que tiene que resolver por sí mismo su base de datos de destino no puede apoyarse en la sesión habitual y hay que conectarlo a propósito al enrutado de Odoo independiente de la base de datos. En cuanto el módulo se añadió a la lista de módulos a nivel de servidor y la ruta se abrió de la forma correcta, el 404 se convirtió en un rechazo o un éxito limpios, exactamente como estaba diseñado. Es de esos detalles que resultan obvios en retrospectiva e invisibles hasta que te topas con ellos.

Ponerlo en línea

Poner la PWA en internet público requirió un pequeño rodeo. Un destino de compartir necesita HTTPS, así que la app necesitaba un subdominio real con un certificado real. El primer dominio que probamos no validaba, porque uno de sus servidores DNS iba muy retrasado y la autoridad de certificación seguía fallando el reto. En lugar de esperar a un servidor de nombres atascado, movimos la app a una zona sana, el certificado se emitió en segundos y el flujo de captura quedó en marcha.

Hay ahí una lección que no paramos de reaprender: cuando un despliegue se atasca por algo ajeno a tu propio código, lo más rápido suele ser rodear la parte rota en lugar de pelearse con ella.

Qué es esto, y qué no es

Mientras construíamos esto echamos un vistazo detenido al propio kit de desarrollo de Meta para sus gafas inteligentes. Es real, pero está dirigido al producto Ray-Ban Display, un dispositivo distinto con una pantalla en la lente. Ese kit es para webapps que se renderizan en las propias gafas. Nuestras gafas no tienen pantalla ni esa API, así que nada de eso aplica a este caso de uso. El diseño honesto aquí no es código en las gafas en absoluto; es salir al encuentro del contenido allí donde realmente aterriza, en el menú de compartir del móvil.

Dónde funciona ahora

El módulo está instalado en nuestro Odoo de producción, la PWA está en marcha sobre HTTPS y el recorrido completo se ha probado de principio a fin: capturar con las gafas, compartir desde la galería, revisar, enviar y ver aparecer una tarea en Capturas Gafas con la foto adjunta. Es una pieza de fontanería pequeña, pero cierra un hueco real: el que hay entre ver algo que merece la pena registrar y tenerlo guardado a buen recaudo donde vive el resto del trabajo.

El siguiente paso obvio es la voz. La misma canalización que lleva una foto puede llevar una nota de audio, y la misma máquina que ejecuta nuestros otros asistentes puede convertir esa nota en una transcripción y en una descripción de tarea lista para leer. Las gafas ya capturan sonido. Solo tenemos que seguir saliendo a su encuentro allí donde aterriza.

Mis skills IA
Un par de docenas de carpetas de conocimiento que convierten un solo modelo en experto de cada rincón de mi trabajo