dienst_echo_whatsappgroep/docs/superpowers/plans/2026-07-12-telegram-watchdog.md
Eddy de Vink 92289adc03 feat: add Telegram watchdog as backup notification channel
- New src/telegramBot.js: separate process for health checks + Telegram notifications
- Updated src/whatsappApi.js notifyAdmin(): falls back to Telegram when WhatsApp API is down
- Updated .env.example with TELEGRAM_* configuration variables
- Design doc and implementation plan
2026-07-12 13:34:04 +02:00

5.9 KiB

Telegram Watchdog Implementation Plan

For agentic workers: Stappen gebruiken checkbox (- [ ]) syntax voor tracking.

Goal: Apart Telegram bot process dat de admin waarschuwt als WhatsApp API of dienst-bot plat ligt.

Architecture: telegramBot.js draait als apart systemd process op nextcloud, gebruikt Telegram Bot API via axios. Dienst-bot roept POST /notify aan als WhatsApp notificatie faalt. Periodieke health checks naar beide services.

Tech Stack: Node.js, Express, axios, dotenv (bestaande dependencies, geen nieuwe)


Task 1: Create src/telegramBot.js

  • Create src/telegramBot.js
require('dotenv').config()
const express = require('express')
const axios = require('axios')

const BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN
const ADMIN_CHAT_ID = process.env.TELEGRAM_ADMIN_CHAT_ID
const PORT = process.env.TELEGRAM_BOT_PORT || 3004
const DIENST_BOT_HEALTH = process.env.DIENST_BOT_HEALTH_URL || 'http://localhost:3002/health'
const WWEBJS_SESSION = process.env.WWEBJS_API_SESSION_URL || 'http://192.168.5.252:3001/session/status/EdGpt'
const CHECK_INTERVAL = parseInt(process.env.HEALTH_CHECK_INTERVAL_MS || '300000', 10)

const app = express()
app.use(express.json())

let dienstBotOk = true
let wwebjsOk = true

function sendTelegram(text) {
  return axios.post(`https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`, {
    chat_id: ADMIN_CHAT_ID,
    text,
    parse_mode: 'Markdown'
  }, { timeout: 10000 })
}

async function startupNotification() {
  try {
    await sendTelegram('✅ Telegram watchdog online — gezondheidschecks actief')
    console.log('Startup notification sent')
  } catch (err) {
    console.error('Failed to send startup notification:', err.message)
  }
}

async function checkHealth() {
  let currentDienstBotOk = true
  let currentWwebjsOk = true

  try {
    await axios.get(DIENST_BOT_HEALTH, { timeout: 5000 })
  } catch {
    currentDienstBotOk = false
  }

  try {
    const res = await axios.get(WWEBJS_SESSION, { timeout: 5000 })
    currentWwebjsOk = res.data?.state === 'CONNECTED'
  } catch {
    currentWwebjsOk = false
  }

  if (dienstBotOk !== currentDienstBotOk) {
    const icon = currentDienstBotOk ? '✅' : '❌'
    const status = currentDienstBotOk ? 'weer online' : 'niet bereikbaar'
    try {
      await sendTelegram(`${icon} dienst-bot ${status}`)
    } catch (err) {
      console.error('Failed to send dienst-bot status:', err.message)
    }
    dienstBotOk = currentDienstBotOk
  }

  if (wwebjsOk !== currentWwebjsOk) {
    const icon = currentWwebjsOk ? '✅' : '❌'
    const status = currentWwebjsOk ? 'weer online' : 'niet bereikbaar'
    try {
      await sendTelegram(`${icon} wwebjs-api ${status}`)
    } catch (err) {
      console.error('Failed to send wwebjs-api status:', err.message)
    }
    wwebjsOk = currentWwebjsOk
  }

  console.log(`Health check: dienst-bot=${currentDienstBotOk ? 'UP' : 'DOWN'}, wwebjs-api=${currentWwebjsOk ? 'UP' : 'DOWN'}`)
}

app.post('/notify', async (req, res) => {
  const { text } = req.body
  if (!text) {
    return res.status(400).json({ success: false, error: 'missing text' })
  }
  try {
    await sendTelegram(`⚠️ ${text}`)
    res.json({ success: true })
  } catch (err) {
    console.error('Failed to forward notification:', err.message)
    res.status(500).json({ success: false, error: err.message })
  }
})

app.get('/health', (req, res) => {
  res.json({ status: 'ok', services: { dienstBot: dienstBotOk, wwebjsApi: wwebjsOk } })
})

startupNotification()
setInterval(checkHealth, CHECK_INTERVAL)
checkHealth()

app.listen(PORT, () => {
  console.log(`telegram-bot listening on port ${PORT}`)
})
  • Update .env.example — add Telegram variables
# Telegram watchdog
TELEGRAM_BOT_TOKEN=
TELEGRAM_ADMIN_CHAT_ID=
TELEGRAM_BOT_PORT=3004
DIENST_BOT_HEALTH_URL=http://localhost:3002/health
WWEBJS_API_SESSION_URL=http://192.168.5.252:3001/session/status/EdGpt
HEALTH_CHECK_INTERVAL_MS=300000

Task 2: Update src/whatsappApi.js — add Telegram fallback

  • Modify notifyAdmin() in src/whatsappApi.js

Replace:

async function notifyAdmin(errorText) {
  const adminNumber = process.env.ADMIN_NUMBER
  if (!adminNumber) {
    console.error('ADMIN_NUMBER not configured, skipping admin notification')
    return
  }
  try {
    await sendTextMessage(adminNumber, `[dienst-bot fout] ${errorText}`)
  } catch (err) {
    console.error('Failed to notify admin:', err.message)
  }
}

With:

async function notifyAdmin(errorText) {
  const adminNumber = process.env.ADMIN_NUMBER
  if (!adminNumber) {
    console.error('ADMIN_NUMBER not configured, skipping admin notification')
    return
  }
  try {
    await sendTextMessage(adminNumber, `[dienst-bot fout] ${errorText}`)
  } catch (err) {
    console.error('WhatsApp admin notification failed, falling back to Telegram:', err.message)
    try {
      const telegramUrl = process.env.TELEGRAM_BOT_URL
      if (telegramUrl) {
        await axios.post(`${telegramUrl}/notify`, { text: errorText }, { timeout: 5000 })
      }
    } catch (telegramErr) {
      console.error('Telegram notification also failed:', telegramErr.message)
    }
  }
}
  • Update .env.example — add TELEGRAM_BOT_URL to dienst-bot section
# Telegram watchdog (fallback when WhatsApp API is down)
TELEGRAM_BOT_URL=http://localhost:3004

Task 3: Update AGENTS.md

  • Add telegram-bot to tables and commands

Add rows:

  • Systemd service: telegram-bot.service

  • Poort: 3004

  • Health check: curl http://localhost:3004/health

  • Commands for status/restart/logs

  • Update release-proces — add step for restarting telegram-bot

Task 4: Deploy & verify on nextcloud

  • ssh aiaiaiaiagent@nextcloud — create systemd service
  • Add TELEGRAM_* vars to .env on nextcloud
  • sudo systemctl daemon-reload && sudo systemctl enable --now telegram-bot
  • Check status & logs
  • Update release-proces: rsync + restart beide services