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 Dinaup instalado. 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étodoQué 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 logTopicPrioridad ntfy
Informationmi-app-alertas-infDefault
Warningmi-app-alertas-wrnDefault
Errormi-app-alertas-errHigh
Fatalmi-app-alertas-ftlUrgent

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.

En esta página