mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-24 20:22:53 +00:00
fix: ntfy webhook now sends plain text instead of JSON
- Modified generatePayloadFromTemplate to skip JSON validation for ntfy - ntfy uses plain text body format, not JSON - Messages now successfully delivered to ntfy topics - Headers for title/priority/tags need dynamic templating support (future enhancement)
This commit is contained in:
@@ -463,7 +463,7 @@ func (n *NotificationManager) sendGroupedWebhook(webhook WebhookConfig, alertLis
|
||||
// The template already has the chat_id embedded
|
||||
}
|
||||
|
||||
jsonData, err = n.generatePayloadFromTemplate(enhanced.PayloadTemplate, data)
|
||||
jsonData, err = n.generatePayloadFromTemplateWithService(enhanced.PayloadTemplate, data, webhook.Service)
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
@@ -539,7 +539,7 @@ func (n *NotificationManager) sendGroupedWebhook(webhook WebhookConfig, alertLis
|
||||
}
|
||||
}
|
||||
|
||||
jsonData, err = n.generatePayloadFromTemplate(enhanced.PayloadTemplate, data)
|
||||
jsonData, err = n.generatePayloadFromTemplateWithService(enhanced.PayloadTemplate, data, webhook.Service)
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
@@ -711,7 +711,7 @@ func (n *NotificationManager) sendWebhook(webhook WebhookConfig, alert *alerts.A
|
||||
}
|
||||
}
|
||||
|
||||
jsonData, err = n.generatePayloadFromTemplate(enhanced.PayloadTemplate, data)
|
||||
jsonData, err = n.generatePayloadFromTemplateWithService(enhanced.PayloadTemplate, data, webhook.Service)
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
@@ -775,7 +775,7 @@ func (n *NotificationManager) sendWebhook(webhook WebhookConfig, alert *alerts.A
|
||||
}
|
||||
}
|
||||
|
||||
jsonData, err = n.generatePayloadFromTemplate(enhanced.PayloadTemplate, data)
|
||||
jsonData, err = n.generatePayloadFromTemplateWithService(enhanced.PayloadTemplate, data, webhook.Service)
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
@@ -841,6 +841,11 @@ func (n *NotificationManager) prepareWebhookData(alert *alerts.Alert, customFiel
|
||||
|
||||
// generatePayloadFromTemplate renders the payload using Go templates
|
||||
func (n *NotificationManager) generatePayloadFromTemplate(templateStr string, data WebhookPayloadData) ([]byte, error) {
|
||||
return n.generatePayloadFromTemplateWithService(templateStr, data, "")
|
||||
}
|
||||
|
||||
// generatePayloadFromTemplateWithService renders the payload using Go templates with service-specific handling
|
||||
func (n *NotificationManager) generatePayloadFromTemplateWithService(templateStr string, data WebhookPayloadData, service string) ([]byte, error) {
|
||||
// Create template with helper functions
|
||||
funcMap := template.FuncMap{
|
||||
"title": func(s string) string {
|
||||
@@ -865,7 +870,13 @@ func (n *NotificationManager) generatePayloadFromTemplate(templateStr string, da
|
||||
return nil, fmt.Errorf("template execution failed: %w", err)
|
||||
}
|
||||
|
||||
// Validate that the generated payload is valid JSON
|
||||
// Skip JSON validation for services that use plain text payloads
|
||||
if service == "ntfy" {
|
||||
// ntfy uses plain text, not JSON
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// Validate that the generated payload is valid JSON for other services
|
||||
var jsonCheck interface{}
|
||||
if err := json.Unmarshal(buf.Bytes(), &jsonCheck); err != nil {
|
||||
log.Error().
|
||||
|
||||
@@ -264,23 +264,24 @@ func GetWebhookTemplates() []WebhookTemplate {
|
||||
Name: "ntfy.sh",
|
||||
URLPattern: "https://ntfy.sh/{topic}",
|
||||
Method: "POST",
|
||||
Headers: map[string]string{"Content-Type": "application/json"},
|
||||
PayloadTemplate: `{
|
||||
"topic": "{{.CustomFields.topic}}",
|
||||
"message": "{{.Message}}",
|
||||
"title": "Pulse Alert: {{.Level | title}}",
|
||||
"priority": {{if eq .Level "critical"}}5{{else if eq .Level "warning"}}4{{else}}3{{end}},
|
||||
"tags": ["{{.Level}}", "{{.Type}}", "pulse"],
|
||||
"click": "{{.Instance}}",
|
||||
"actions": [
|
||||
{
|
||||
"action": "view",
|
||||
"label": "View in Pulse",
|
||||
"url": "{{.Instance}}"
|
||||
}
|
||||
],
|
||||
"markdown": true
|
||||
}`,
|
||||
Headers: map[string]string{
|
||||
"Content-Type": "text/plain",
|
||||
"Title": "Pulse Alert",
|
||||
"Priority": "urgent",
|
||||
"Tags": "pulse,monitoring",
|
||||
},
|
||||
PayloadTemplate: `🚨 {{.Level | title}} Alert: {{.ResourceName}}
|
||||
|
||||
{{.Message}}
|
||||
|
||||
📊 Details:
|
||||
• Node: {{.Node}}
|
||||
• Type: {{.Type | title}}
|
||||
• Value: {{if or (eq .Type "diskRead") (eq .Type "diskWrite")}}{{printf "%.1f" .Value}} MB/s{{else}}{{printf "%.1f" .Value}}%{{end}}
|
||||
• Threshold: {{if or (eq .Type "diskRead") (eq .Type "diskWrite")}}{{printf "%.0f" .Threshold}} MB/s{{else}}{{printf "%.0f" .Threshold}}%{{end}}
|
||||
• Duration: {{.Duration}}
|
||||
|
||||
View in Pulse: {{.Instance}}`,
|
||||
Instructions: "1. Choose a topic name (e.g., 'my-pulse-alerts')\n2. URL format: https://ntfy.sh/YOUR_TOPIC\n Or for self-hosted: https://your-ntfy-server/YOUR_TOPIC\n3. Optional: Add authentication token in headers if required\n4. Subscribe to the topic in your ntfy app using the same topic name",
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user