Notificaciones ntfy
NtfyClientC publica notificaciones push en un topic de ntfy con título, prioridad, Markdown, botones y adjuntos, por separado o conectado a Dinaup.Logs.
El módulo dinaup.ntfy del paquete Dinaup publica notificaciones push en un topic de ntfy desde cualquier app. Se usa por separado, para enviar avisos concretos, o conectado a Dinaup.Logs para que cada Information, Warning, Error y Fatal dispare una notificación.
Antes de empezar
- Paquete
Dinaupinstalado. Ver SDK .NET. - La URL de un servidor ntfy (público o propio) y, para topics protegidos, un token de acceso.
using Dinaup.Ntfy;Crear el cliente
// Servidor público o propio
var ntfy = new NtfyClientC("https://ntfy.tu-dominio.com");
// Con token de acceso para topics protegidos
var ntfyAuth = new NtfyClientC("https://ntfy.tu-dominio.com", "tk_tu-token");Con NtfyClientOptions ajustas más opciones; hay un cuarto constructor que además recibe tu propio HttpClient:
var ntfy = new NtfyClientC(new NtfyClientOptions
{
ServerUrl = "https://ntfy.tu-dominio.com",
AccessToken = "tk_tu-token",
DefaultTopic = "mi-app",
DefaultPriority = NtfyPriority.Default,
DefaultIcon = "https://cdn.tu-dominio.com/icono.png",
Timeout = TimeSpan.FromSeconds(30)
});ServerUrl e IsAuthenticated describen el cliente. Implementa IDisposable.
Enviar
// Mensaje simple
await ntfy.SendAsync("mi-app", "Backup completado");
// Con título
await ntfy.SendAsync("mi-app", "Backup completado", "Copias");
// Con título y prioridad
await ntfy.SendAsync("mi-app", "Stock por debajo del mínimo", "Aviso de inventario", NtfyPriority.High);Las prioridades son Minimum, Low, Default, High y Urgent. Cada envío devuelve un NtfyResult con IsSuccess, ErrorMessage y MessageId, y admite un CancellationToken al final.
| Método | Qué envía |
|---|---|
SendAsync(topic, message), (topic, message, title), (topic, message, title, priority) | Texto plano. |
SendMarkdownAsync(topic, message, title, priority) | Cuerpo en Markdown. |
SendWithClickUrlAsync(topic, message, clickUrl) y (topic, message, title, clickUrl, priority) | Abre una URL al tocar la notificación. |
SendWithActionsAsync(topic, message, actions) y (topic, message, title, priority, actions) | Botones de acción, un NtfyAction[]. |
SendWithAttachmentUrlAsync(topic, message, attachmentUrl, filename) y (topic, message, title, attachmentUrl, filename, priority) | Adjunta un archivo por URL. |
SendWithAttachmentAsync(topic, message, fileBytes, filename, mimeType) y (topic, message, title, fileBytes, filename, mimeType, priority) | Adjunta un archivo por bytes. |
SendAppStartupAsync(topic, additionalInfo), SendAppShutdownAsync(topic, reason), SendAppErrorAsync(topic, exception, context) | Avisos de ciclo de vida de la app con nombre, versión y entorno. |
Los botones se construyen con NtfyAction.CreateViewAction(label, url, clearOnClick) (abre una URL) y NtfyAction.CreateHttpAction(label, url, clearOnClick) (hace una petición HTTP):
await ntfy.SendWithActionsAsync("mi-app", "Pedido 1234 pendiente de revisar", new[]
{
NtfyAction.CreateViewAction("Abrir pedido", "https://play.dinaup.com/pedidos/1234"),
NtfyAction.CreateHttpAction("Aprobar", "https://api.tu-dominio.com/pedidos/1234/aprobar", clearOnClick: true)
});Conexión con los logs
Pasa el cliente ntfy y un topic a Logs.Initialize y los logs publican los avisos:
using Dinaup;
using Dinaup.Ntfy;
var loki = new Logs.LokiConfig { Endpoint = "https://loki.tu-dominio.com/loki/api/v1/push" };
var ntfy = new NtfyClientC("https://ntfy.tu-dominio.com", "tk_tu-token");
Logs.Initialize(loki, ntfy, "mi-app-alertas");Desde ese momento cada Logs.Information, Logs.Warning, Logs.Error y Logs.Fatal publica una notificación en segundo plano; la sobrecarga de Logs.Information con excepción no publica. El nivel decide el sufijo del topic y la prioridad:
| Nivel de log | Topic | Prioridad ntfy |
|---|---|---|
Information | mi-app-alertas-inf | Default |
Warning | mi-app-alertas-wrn | Default |
Error | mi-app-alertas-err | High |
Fatal | mi-app-alertas-ftl | Urgent |
El cuerpo lleva el mensaje con sus valores y una línea con nivel, app, versión, entorno, máquina y hora. Si hay excepción, añade su tipo, su mensaje y los primeros 300 caracteres de la pila.
El envío desde logs se limita a 60 notificaciones cada 20 segundos. Los avisos que superan el límite se descartan; el log se escribe igual.
Notificaciones manuales desde Logs
Con Logs inicializado con ntfy, envía avisos sin pasar por un nivel de log:
await Logs.SendNotificationAsync("Cierre de caja pendiente", "Recordatorio", NtfyPriority.Default);
await Logs.SendErrorNotificationAsync(ex, "Importador nocturno");
await Logs.SendShutdownNotificationAsync("Despliegue programado");Logs.IsNtfyConfigured indica si la conexión con ntfy está activa. Los métodos no lanzan si ntfy no está configurado.
Para avisos que salen de Dinaup hacia otros sistemas (un pedido nuevo, una ficha que cambia), usa los webhooks salientes.