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
This commit is contained in:
parent
586f4994a6
commit
92289adc03
5 changed files with 458 additions and 1 deletions
101
src/telegramBot.js
Normal file
101
src/telegramBot.js
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
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}`)
|
||||
})
|
||||
|
|
@ -73,7 +73,15 @@ async function notifyAdmin(errorText) {
|
|||
try {
|
||||
await sendTextMessage(adminNumber, `[dienst-bot fout] ${errorText}`)
|
||||
} catch (err) {
|
||||
console.error('Failed to notify admin:', err.message)
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue