diff --git a/PROJECT_STATUS.md b/PROJECT_STATUS.md index 7ea1161..a841e07 100644 --- a/PROJECT_STATUS.md +++ b/PROJECT_STATUS.md @@ -78,6 +78,8 @@ ventana de procesamiento en vez de bloquear un segundo por sensor. - `GET /api/config/notifications` devuelve configuracion redactada. - `POST /api/config/notifications` valida y persiste canales con token. - El recolector despacha notificaciones desde eventos de `logs/alarms.csv`. +- `docs/TELEGRAM_BOT_SETUP.md` documenta creacion del bot, obtencion de + `chatId`, configuracion, pruebas y diagnostico. ## Modos diff --git a/README.md b/README.md index 0979e89..f99609d 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,9 @@ envia notificaciones cuando una alarma persistente alcanza `minSeverity`. La API expone configuracion redactada en `GET /api/config/notifications`; guardar requiere token y nunca devuelve secretos sin redaccion. +La configuracion completa del bot, `chatId`, pruebas y diagnostico esta en +[`docs/TELEGRAM_BOT_SETUP.md`](docs/TELEGRAM_BOT_SETUP.md). + ## Archivos de datos - Lecturas actuales: `data/EZORTD.json`, `EZOPH.json`, `EZODO.json`, @@ -152,6 +155,7 @@ timestamp,value - Estado actual: [`PROJECT_STATUS.md`](PROJECT_STATUS.md) - Comandos y calibración: [`docs/EZO_COMMANDS.md`](docs/EZO_COMMANDS.md) - Despliegue: [`docs/RASPBERRY_PI_DEPLOYMENT.md`](docs/RASPBERRY_PI_DEPLOYMENT.md) +- Telegram: [`docs/TELEGRAM_BOT_SETUP.md`](docs/TELEGRAM_BOT_SETUP.md) - Diseño extendido: [`ARCHITECTURE.md`](ARCHITECTURE.md) No se utiliza un driver personalizado del kernel. Linux ya proporciona la capa diff --git a/docs/TELEGRAM_BOT_SETUP.md b/docs/TELEGRAM_BOT_SETUP.md new file mode 100644 index 0000000..6fdc72b --- /dev/null +++ b/docs/TELEGRAM_BOT_SETUP.md @@ -0,0 +1,295 @@ +# Guia de configuracion de Telegram + +Esta guia explica como activar notificaciones de alarmas del Photobioreactor +Dashboard hacia Telegram. El envio ocurre desde el backend de la Raspberry Pi, +por lo que las alertas pueden salir aunque el navegador del dashboard este +cerrado. + +## Requisitos + +- Raspberry Pi con acceso a Internet. +- API y recolector funcionando mediante `systemd`. +- Un token de API configurado en `API_AUTH_TOKEN` si se desea proteger cambios + desde el dashboard. +- Un bot de Telegram creado con BotFather. +- Un `chatId` de usuario, grupo o canal donde el bot pueda escribir. + +## Flujo general + +```text +Sensor EZO + | +Recolector de adquisicion + | +Evaluacion de umbrales + | +Evento de alarma o recuperacion + | +logs/alarms.csv + | +api/notification-service.js + | +Telegram Bot API + | +Chat configurado +``` + +El sistema no envia mensajes en cada lectura. Solo envia notificaciones cuando +se genera un evento de alarma elegible, por ejemplo una transicion a `WARNING`, +`CRITICAL`, `OFFLINE` o una recuperacion si la severidad minima lo permite. + +## Crear el bot + +1. Abra Telegram y busque `@BotFather`. +2. Envie: + +```text +/newbot +``` + +3. Asigne un nombre visible al bot. +4. Asigne un usuario terminado en `bot`, por ejemplo: + +```text +photobioreactor_alerts_bot +``` + +5. BotFather entregara un token con formato parecido a: + +```text +1234567890:AAExampleTokenDoNotShare +``` + +Guarde este token como secreto. No lo publique en Git, capturas o mensajes. + +## Obtener el chatId + +### Chat directo con el bot + +1. Abra el bot recien creado. +2. Presione `Start` o envie cualquier mensaje, por ejemplo: + +```text +hola +``` + +3. En una terminal, consulte las actualizaciones: + +```bash +curl "https://api.telegram.org/bot/getUpdates" +``` + +4. Busque el campo `chat.id`. El valor puede verse como: + +```json +"chat":{"id":123456789,"first_name":"Cristian","type":"private"} +``` + +En este ejemplo, el `chatId` es: + +```text +123456789 +``` + +### Grupo de Telegram + +1. Agregue el bot al grupo. +2. Envie un mensaje dentro del grupo mencionando o usando el bot. +3. Ejecute: + +```bash +curl "https://api.telegram.org/bot/getUpdates" +``` + +4. Busque el `chat.id` del grupo. Normalmente es negativo, por ejemplo: + +```text +-1001234567890 +``` + +Si no aparece ningun resultado, envie otro mensaje en el grupo y repita la +consulta. En algunos grupos puede ser necesario permitir que el bot lea mensajes +o usar comandos dirigidos al bot. + +## Configuracion desde el dashboard + +1. Abra el dashboard en la red local de la Raspberry Pi. +2. Si `API_AUTH_TOKEN` esta configurado, escriba ese valor en el campo `Token + API`. +3. Vaya al panel de notificaciones. +4. Active `Activas`. +5. Seleccione la severidad minima: + +| Severidad minima | Resultado | +|---|---| +| `WARNING` | Envia warnings, offline y criticos | +| `OFFLINE` | Envia offline y criticos | +| `CRITICAL` | Solo envia alarmas criticas | + +6. Active `Telegram`. +7. Escriba el `Chat ID`. +8. Escriba el `Bot token`. +9. Guarde la configuracion. + +Despues de guardar, el backend nunca devuelve el token completo al navegador. +El dashboard lo mostrara como configurado y en guardados posteriores puede dejar +el campo de token vacio para conservar el valor existente. + +## Configuracion directa en Raspberry Pi + +En produccion, el instalador usa: + +```text +/etc/photobioreactor/notifications.json +``` + +La ruta se define en: + +```text +NOTIFICATION_CONFIG_FILE=/etc/photobioreactor/notifications.json +``` + +Ejemplo de configuracion: + +```json +{ + "enabled": true, + "minSeverity": "CRITICAL", + "channels": { + "webhook": { + "enabled": false, + "url": "", + "headers": {} + }, + "telegram": { + "enabled": true, + "botToken": "1234567890:AAExampleTokenDoNotShare", + "chatId": "123456789" + } + } +} +``` + +Proteja el archivo porque contiene secretos: + +```bash +sudo chown photobioreactor:photobioreactor /etc/photobioreactor/notifications.json +sudo chmod 600 /etc/photobioreactor/notifications.json +sudo systemctl restart photobioreactor-acquisition +``` + +## Prueba manual de Telegram + +Antes de probar el dashboard, confirme que Telegram acepta el token y el chat: + +```bash +curl -X POST "https://api.telegram.org/bot/sendMessage" \ + -H "Content-Type: application/json" \ + -d '{"chat_id":"","text":"Prueba de alarmas del fotobiorreactor"}' +``` + +Si Telegram responde con `"ok":true`, el bot y el chat estan bien configurados. + +## Prueba desde el sistema + +1. Confirme que el recolector esta activo: + +```bash +systemctl status photobioreactor-acquisition +``` + +2. Revise eventos recientes: + +```bash +tail -n 20 /opt/photobioreactor/logs/alarms.csv +``` + +3. Genere una condicion de alarma de prueba ajustando temporalmente un umbral + desde el dashboard. Por ejemplo, establezca un maximo de temperatura por + debajo de la lectura actual para forzar `CRITICAL`. +4. Espere el siguiente ciclo de adquisicion. +5. Confirme que se registro el evento y llego el mensaje. +6. Restaure el umbral correcto. + +Evite hacer esta prueba durante una calibracion real o una corrida experimental +critica. + +## Mensaje enviado + +El mensaje tiene este formato: + +```text +Photobioreactor alarm: CRITICAL +Sensor: temperature +Value: 31.2 +Message: Temperature is above configured range. +Time: 2026-06-27T12:00:00.000Z +``` + +El texto se construye en `api/notification-service.js`. Si mas adelante se +necesita un formato distinto, ese es el punto central para modificarlo. + +## Seguridad recomendada + +- Configure `API_AUTH_TOKEN` en produccion. +- No suba tokens de Telegram al repositorio. +- Use `/etc/photobioreactor/notifications.json` para secretos en Raspberry Pi. +- Mantenga permisos `600` en el archivo de notificaciones. +- Si el token se expone, regenere el token desde BotFather. +- No publique el dashboard directamente a Internet. + +## Diagnostico + +### No llega ningun mensaje + +- Verifique Internet en la Raspberry: + +```bash +curl https://api.telegram.org +``` + +- Verifique token y chat con la prueba manual de `sendMessage`. +- Confirme que `enabled` y `channels.telegram.enabled` estan en `true`. +- Confirme que `minSeverity` no esta filtrando el evento. +- Confirme que realmente hubo una transicion de alarma en `logs/alarms.csv`. + +### El dashboard no permite guardar + +- Si `API_AUTH_TOKEN` esta configurado, debe escribirlo en el campo `Token API`. +- Revise rate limit si se hicieron muchos cambios seguidos. +- Consulte logs de la API: + +```bash +journalctl -u photobioreactor-api -f +``` + +### El bot responde en chat directo pero no en grupo + +- Confirme que el bot esta agregado al grupo. +- Use el `chatId` del grupo, no el chat privado. +- En grupos, el `chatId` normalmente es negativo. +- Envie un mensaje nuevo al grupo y repita `getUpdates`. + +### El token aparece como `[configured]` + +Ese comportamiento es correcto. El backend redacta el secreto cuando el +dashboard consulta la configuracion. Para cambiar el token, escriba uno nuevo y +guarde. Para conservarlo, deje el campo vacio. + +## Estado actual de implementacion + +Implementado: + +- Configuracion persistente en `config/notifications.json` o + `NOTIFICATION_CONFIG_FILE`. +- Canal Telegram mediante Bot API `sendMessage`. +- Redaccion de token hacia el frontend. +- Conservacion de token existente desde el dashboard. +- Filtro por severidad minima. +- Integracion con eventos generados por el recolector. + +Pendiente de validacion en Raspberry: + +- Envio real desde la red donde trabajara el equipo. +- Comportamiento durante desconexiones fisicas de sensores. +- Registro operativo de errores de envio en corridas largas.