fix: telegram webhook payload format and pbs connection issues (fixes #294)

- add proper telegram bot api support with chat_id and text fields
- fix frontend pbs red dot display (was checking 'error' instead of 'unhealthy')
- fix qemu guest agent memory reporting (fallback to mem when freemem is 0)
- extract chat_id from telegram webhook urls when present
This commit is contained in:
Pulse Monitor
2025-08-11 09:38:09 +00:00
parent 2f2ab19c0b
commit 94a74fdcfe
4 changed files with 45 additions and 6 deletions
+10
View File
@@ -337,8 +337,17 @@ func (h *NotificationHandlers) TestWebhook(w http.ResponseWriter, r *http.Reques
}
if err := json.Unmarshal(bodyBytes, &serviceCheck); err == nil && serviceCheck.Service != "" {
webhook.Service = serviceCheck.Service
// Also set it in the basic webhook for consistency
basicWebhook.Service = serviceCheck.Service
webhook.WebhookConfig.Service = serviceCheck.Service
}
log.Info().
Str("service", webhook.Service).
Str("url", webhook.URL).
Str("name", webhook.Name).
Msg("Testing webhook")
// Get template for the service
templates := notifications.GetWebhookTemplates()
for _, tmpl := range templates {
@@ -350,6 +359,7 @@ func (h *NotificationHandlers) TestWebhook(w http.ResponseWriter, r *http.Reques
for k, v := range tmpl.Headers {
webhook.Headers[k] = v
}
log.Info().Str("service", webhook.Service).Msg("Found template for service")
break
}
}
+20 -6
View File
@@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"strings"
"sync"
"text/template"
@@ -466,18 +467,18 @@ func (n *NotificationManager) sendWebhook(webhook WebhookConfig, alert *alerts.A
var jsonData []byte
var err error
// Check if this is a Discord webhook and use the proper template
if webhook.Service == "discord" {
// Check if this is a service-specific webhook and use the proper template
if webhook.Service == "discord" || webhook.Service == "telegram" {
// Convert to enhanced webhook to use template
enhanced := EnhancedWebhookConfig{
WebhookConfig: webhook,
Service: "discord",
Service: webhook.Service,
}
// Get Discord template
// Get service template
templates := GetWebhookTemplates()
for _, tmpl := range templates {
if tmpl.Service == "discord" {
if tmpl.Service == webhook.Service {
enhanced.PayloadTemplate = tmpl.PayloadTemplate
break
}
@@ -485,13 +486,26 @@ func (n *NotificationManager) sendWebhook(webhook WebhookConfig, alert *alerts.A
// Prepare data and generate payload
data := n.prepareWebhookData(alert, nil)
// For Telegram, extract chat_id from URL if present
if webhook.Service == "telegram" && strings.Contains(webhook.URL, "chat_id=") {
// Extract chat_id from URL query params
if u, err := url.Parse(webhook.URL); err == nil {
chatID := u.Query().Get("chat_id")
if chatID != "" {
data.ChatID = chatID
}
}
}
jsonData, err = n.generatePayloadFromTemplate(enhanced.PayloadTemplate, data)
if err != nil {
log.Error().
Err(err).
Str("webhook", webhook.Name).
Str("service", webhook.Service).
Str("alertID", alert.ID).
Msg("Failed to generate Discord payload")
Msg("Failed to generate webhook payload")
return
}
} else {
@@ -51,6 +51,7 @@ type WebhookPayloadData struct {
CustomFields map[string]interface{}
AlertCount int
Alerts []*alerts.Alert // For grouped alerts
ChatID string // For Telegram webhooks
}
// SendEnhancedWebhook sends a webhook with template support
@@ -45,6 +45,20 @@ func GetWebhookTemplates() []WebhookTemplate {
}`,
Instructions: "1. In Discord, go to Server Settings > Integrations > Webhooks\n2. Create a new webhook and copy the URL\n3. Paste the URL here (format: https://discord.com/api/webhooks/...)",
},
{
Service: "telegram",
Name: "Telegram Bot",
URLPattern: "https://api.telegram.org/bot{bot_token}/sendMessage",
Method: "POST",
Headers: map[string]string{"Content-Type": "application/json"},
PayloadTemplate: `{
"chat_id": "{{.ChatID}}",
"text": "🚨 *Pulse Alert: {{.Level | title}}*\n\n{{.Message}}\n\n📊 *Details:*\n• Resource: {{.ResourceName}}\n• Node: {{.Node}}\n• Type: {{.Type | title}}\n• Value: {{printf "%.1f" .Value}}%\n• Threshold: {{printf "%.0f" .Threshold}}%\n• Duration: {{.Duration}}\n\n🔗 [View in Pulse]({{.Instance}})",
"parse_mode": "Markdown",
"disable_web_page_preview": true
}`,
Instructions: "1. Create a bot with @BotFather on Telegram\n2. Get your bot token\n3. Get your chat ID by messaging the bot and visiting: https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates\n4. URL format: https://api.telegram.org/bot<BOT_TOKEN>/sendMessage",
},
{
Service: "slack",
Name: "Slack Incoming Webhook",