Crea tu propio servidor de notificaciones con Ntfy
Gestiona tus notificaciones con la privacidad que se merecen y desde cualquier dispositivo
En varias entradas ya he comentado cómo recibir notificaciones en nuestra cuenta de Telegram, y si bien es un servicio que he estado usando de manera intensiva, siempre he tenido el miedo a qué pasaría si el día de mañana Telegram decide cerrar su servicio, o simplemente se cae y no puedo enterarme de lo que mis aplicaciones tratan de informarme... O simplemente, quiero manejar cierta información sensible que no me apetece que pase por las manos de Telegram o Google o Apple (para las notificaciones que recibo en el móvil).
Llevaba un tiempo detrás de esta idea y no voy a negar que, en varias ocasiones, he coqueteado con Gotify sin que, en ninguna de ellas, me convenciera demasiado. No me malinterpretéis, es un servicio de notificaciones genial y que funciona de manera muy fluida. Pero tiene ciertas características (aplicaciones por usuario, lecturas protegidas pero no escrituras en los tópicos, etc) que no me terminaban de convencer. Además, está bien para recibir notificaciones en el móvil, pero... se me antoja inútil sólo para eso.
Tras investigar durante un tiempo, dejar el tema, volver a retormarlo, volverlo a dejar... He terminado dando con Ntfy.sh (pronunciado notify según su creador). Se trata de un servicio de publicación-suscripción muy parecido a Gotify o, casi mejor, a MQTT (salvo que funciona sobre REST). Nos permite publicar y suscribirnos a tópicos sin necesidad de crearlos antes, además de soportar autenticación y roles (de manera básica por ahora). Y por si esto no fuera poco, tiene clientes para suscribirse y publicar desde prácticamente cualquier plataforma, lo que nos permite ampliar mucho su utilidad (podemos crear un script que se suscriba a un tópico y actúe en función de los mensajes que reciba, automatizar procesos, etc), además de que, en el caso de Android, nos puede servir como servidor de notificaciones, pues implementa el estándar Unified Push.
Me enrollo como las persianas, y la mejor manera de ver sus ventajas es que os cuente cómo instalarlo y algunos ejemplos de uso que le estoy dando. Así pues... ¡al lío!
Instalación y configuración de Ntfy.sh
Si bien se puede instalar como un simple binario (que además nos sirve igual como servidor que como cliente), en mi máquina lo tengo corriendo con Docker, por pura simplicidad de mantenimiento. No descarto el uso del binario en, por ejemplo, el ordenador, con el fin de usarlo como cliente y recibir notificaciones nativas, en lugar de necesitar del navegador como hago actualmente.
Comencemos creando nuestro fichero docker-compose.yml
con la siguiente información:
Como se puede ver, el docker-compose.yml
es muy sencillo. Apenas habrá que modificar el user:group
para que cuadre con el que tengamos en nuestra máquina (lo cual podéis hacer simplemente ejecutando el comando id
en Linux) y conectarlo a la red que prefiramos. El servicio se levanta en el puerto 80, por lo que si queremos acceder directamente a él, deberemos exponerlo. En mi caso, últimamente estoy haciendo bastante uso de los túneles de Cloudflare, pues me facilitan mucho la vida para probar estos pequeños desarrollos y, en algunos casos, para exponer servicios al exterior sin mayor complejidad.
Una vez tenemos nuestro fichero preparado, deberemos crear 2 carpetas: cache
y conf
. La primera servirá para almacenar los datos temporales de Ntfy, como las imágenes o ficheros que enviemos por la notificación (sí, podremos hacer eso), durante el tiempo que definamos en su configuración.
Por otro lado, la carpeta conf
contendrá las bases de datos SQLite con la información de los usuarios dados de alta, los roles y permisos, y la información de los mensajes en caché. Además, tendremos ahí un fichero YML con la configuración del servidor, el cual deberá llamarse server.yml
y del cual nos podemos bajar una plantilla de este enlace. Es bastante descriptivo y está muy bien documentado, así que sólo mencionaré lo más básico y necesario para tener nuestro servicio disponible lo antes posible:
base-url
: Deberemos especificar aquí la URL pública de nuestro servidor Ntfy. Como dice en la documentación, será necesaria para usarlo con dispositivos iOS, así como para los enlaces de descarga de ficheros, el envío de correos electrónicos para mostrar como notificación, como puerta de entrada para gestionar las notificaciones en la red de Matrix...cache-file
: Ruta hasta el ficherocache.db
dentro de nuestro contenedor. Según hemos mapeado las carpetas, ésta puede ser/etc/ntfy/cache.db
.cache-duration
: El tiempo durante el cual se mantendrán los mensajes y ficheros en caché. Por defecto será de 12 horas si no especificamos nada.auth-file
: Ruta hasta el fichero que contiene la información de usuarios y roles. Al igual que en el caso de la caché, podemos especificar/etc/ntfy/auth.db
auth-default-access
: El acceso por defecto a los tópicos de nuestro servidor. Si vamos a usarlo para nuestro propio fin privado, lo suyo es que definamos aquídeny-all
. Será la configuración por defecto para los tópicos que no requieran de usuario y contraseña. También podemos especificar, si así lo preferimos,read-write
(es el valor por defecto si no ponemos nada),read-only
owrite-only
.behind-proxy
: Si el servicio está detrás de un proxy, como es mi caso con Cloudflare o si lo tenemos tras un Traefik o un Nginx simplemente, deberemos especificarlo con untrue
.attachment-cache-dir
: Ruta hacia el directorio donde se almancenarán los ficheros en caché. En base a nuestrodocker-compose.yml
, ésta puede ser/var/cache/ntfy
.attachment-total-size-limit
: Será el límite del tamaño de nuestra caché en disco. Si no vamos a hacer un uso intensivo del almacenamiento, podemos limitarla a1G
perfectamente (y evitamos que se nos llene el disco por una mala gestión o acciones malintencionadas).attachment-file-size-limit
: Aquí indicaremos el tamaño máximo por fichero en la caché. Un tamaño de100M
es más que suficiente (sobre todo si pensamos enviar logs o imágenes).attachment-expiry-duration
: El tiempo durante el cual los ficheros permanecerán en la caché. Por defecto es de 12 horas. Yo aquí suelo poner el mismo tiempo que encache-duration
, pues para mí, en cuanto se borre el mensaje ya no será necesario el fichero, pero depende ya de cada uno y el uso que le quiera dar (ya que podremos copiar la URL del fichero y que éste esté disponible incluso cuando la notificación haya expirado).upstream-base-url
: URL para hacer uso de los servicios de notificaciones de Google/Apple (es decir, Firebase o APNS-connected, respectivamente). Podemos definir aquí el servidor dehttps://ntfy.sh
si vamos a usar este servicio.global-topic-limit
: Límite de tópicos a crear antes de que el servidor rechace aceptar nuevos. Si no vamos a utilizar muchos, un valor de 20 o 30 puede ser más que suficiente.log-level
: Nivel de log de la aplicación.WARN
oERROR
estará bien cuando usemos el servicio de manera continua y no necesitemos monitorizar qué ocurre.
Una vez tenemos nuestro fichero docker-compose.yml
y el server.yml
correctamente configurados, podemos arrancar la aplicación. Un simple docker compose up -d
y podremos acceder vía web a través de la URL que le hayamos asignado (por ejemplo: https://ntfy.example.org/
).
Gestión de usuarios y permisos
Una vez tenemos nuestro servidor de notificaciones corriendo, es buena idea crear los usuarios que vayamos a necesitar. Para ello accedemos a la consola (estando con Docker podemos hacerlo con el comando docker exec -ti ntfy sh
) y una vez dentro, el comando ntfy --help
será nuestro amigo.
Todos los comandos, seguidos de un--help
nos darán toda la información que necesitamos para utilizarlos. Así,ntfy --help
nos informará de qué podemos hacer con él, mientras quentfy access --help
nos mostrará la información relevante al comando de control de permisos.
Usuarios
Para listar los usuarios, bastará con ejecutar el comando ntfy user list
. Si queremos dar de alta un nuevo usuario, con ntfy user add pepito
nos pedirá la contraseña para él, y si queremos que sea administrador, basta con ntfy user add --role=admin pepito
. Para borrarlo, ntfy user del pepito
, cambiar su contraseña ntfy user change-pass
y su rol ntfy user change-role user|admin
en función del que le queramos dar.
Hay un usuario reservado, que es everyone
o *
, el cual hará referencia a los usuarios anónimos.
Los usuarios con rol de administrador pueden leer y escribir en todos los tópicos, no necesitaremos crear una configuración para ellos.
Permisos
Para gestionar los permisos, el comando ntfy access
nos mostrará la configuración actual. Pongamos por ejemplo que queremos que nuestro usuario Pepito pueda publicar y suscribirse a home-info
, home-alertas
, home-debug
... Y cualquier otro tópico que empiece por home-
. Puesto que esos tópicos los usará él y sólo él, haremos uso de ntfy access pepito "home-*" rw
.
Por otro lado, resulta que también le hemos dado permisos, sin querer claro está, al tópico cosas-importantes
, y no queremos que se suscriba más. Con un simple ntfy access --reset pepito cosas-importantes
lo sacaremos del tópico.
Si queremos que nuestro servidor de notificaciones se pueda usar por aplicaciones en Android que soporten Unified Push... Algo tan simple comontfy access everyone "up*" rw
ontfy access * "up*" rw
será más que suficiente.
Una vez hemos terminado, tanto el comando ntfy user list
como el comando ntfy access
(son sinónimos en realidad) nos mostrarán algo como lo siguiente:
Como veis, es bastante sencillo de manejar.
Suscribirse a tópicos
Los tópicos en Ntfy no son más que rutas en la URL, algo tan sencillo como suscribirse al tópico alertas
se hace con la URL https://ntfy.example.org/alertas
.
Interfaz web
Ntfy nos proporciona una interfaz web responsiva (accesible desde la URL principal), desde la cual nos podremos suscribir a los tópicos que deseemos, además de poder usar otros servidores (como el propio de https://ntfy.sh
).
Dispositivos móviles
En Android, es bastante similar. Nos podemos bajar la aplicación desde la Google Play Store o desde F-Droid y suscribirnos a lo que nos interese, además de permitirnos integrarnos con más aplicaciones (como Tasker).
CLI y API
El servicio nos ofrece 2 maneras de consumir mensajes orientados a la automatización y la ejecución de scripts. Éstos son mediante el uso de un binario ntfy-cli
o a través de su API.
Publicar en tópicos
Para publicar mensajes, tenemos varias opciones: Podemos hacer uso del binario de ntfy-cli
que nos proporciona su desarrollador, podemos hacerlo desde la interfaz web o, directamente, mediante el uso del comando curl
. También tenemos disponibles librerías para Go, Java, Python...
Un ejemplo muy sencillo, sería el uso del comando curl
para enviar una notificación de prueba:
El resultado de ese comando se verá así en la web:
Pero podemos ir más allá. Podemos agregar tags que pueden convertirse en emoji en el mensaje, agregar el usuario y la contraseña si es un tópico protegido, establecer la prioridad de la notificación (del 1 al 5, siendo de menos a más, o mediante palabras reservadas: min
, low
, default
, high
o max|urgent
). También podemos agregar imágenes, enlaces, indicar acciones al pulsar sobre la notificación... ¡Incluso podemos postponer las notificaciones a una hora determinada o pasado X tiempo!
También podemos definir botones de acción (por ejemplo, si recibimos una notificación de que la temperatura en casa se ha disparado, permitir apagar la calefacción desde ahí mismo, llamando a un endpoint, por ejemplo).
Las posibilidades que ofrece son inmensas, y os invito a pasaros por la documentación, pues es tan extensa que en una entrada sería inviable comentar todas las opciones. Además está soportado cada vez por más servicios (el más relevante para mí, Uptime Kuma).
En mi caso, lo estoy orientando a centralizar todas las notificaciones que ahora mismo tengo repartidas por los bot de Telegram, Matrix... Y además usarlo como servidor de notificaciones para Matrix y la red de Mastodon (aún estoy probando esta parte).
¡Y esto es todo por el momento! Seguramente en un futuro le dé mucho más uso, sobre todo cuando me meta con las automatizaciones, y ya os iré contando. De momento... me mantiene informado de todo lo que ocurre en cada momento en mis servicios, que ya es decir.
Si te ha gustado la entrada, o te ha sido útil y quieres ayudarme a pagar los gastos que conlleva el servidor y mantener así el blog libre completamente de anuncios, puedes hacer una donación en Bitcoin en la siguiente dirección: