From 1470afb71572f7e95597285eb4d1dac40b69979f Mon Sep 17 00:00:00 2001 From: binwiederhier Date: Sun, 27 Jul 2025 10:15:48 +0200 Subject: [PATCH] Make templateMode more understandable --- server/server.go | 14 ++++++-------- server/types.go | 37 ++++++++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/server/server.go b/server/server.go index 0b7880cd..ac7b10dc 100644 --- a/server/server.go +++ b/server/server.go @@ -992,12 +992,10 @@ func (s *Server) parsePublishParams(r *http.Request, m *message) (cache bool, fi return false, false, "", "", "", false, errHTTPBadRequestPhoneNumberInvalid } template = templateMode(readParam(r, "x-template", "template", "tpl")) - var messageStr string - if template.Enabled() && template.Name() == "" { - // don't convert "\n" to literal newline for inline templates - messageStr = readParam(r, "x-message", "message", "m") - } else { - messageStr = strings.ReplaceAll(readParam(r, "x-message", "message", "m"), "\\n", "\n") + messageStr := readParam(r, "x-message", "message", "m") + if !template.InlineMode() { + // Convert "\n" to literal newline everything but inline mode + messageStr = strings.ReplaceAll(messageStr, "\\n", "\n") } if messageStr != "" { m.Message = messageStr @@ -1125,8 +1123,8 @@ func (s *Server) handleBodyAsTemplatedTextMessage(m *message, template templateM return errHTTPEntityTooLargeJSONBody } peekedBody := strings.TrimSpace(string(body.PeekedBytes)) - if templateName := template.Name(); templateName != "" { - if err := s.renderTemplateFromFile(m, templateName, peekedBody); err != nil { + if template.FileMode() { + if err := s.renderTemplateFromFile(m, template.FileName(), peekedBody); err != nil { return err } } else { diff --git a/server/types.go b/server/types.go index ea6b8615..65492e46 100644 --- a/server/types.go +++ b/server/types.go @@ -245,19 +245,46 @@ func (q *queryFilter) Pass(msg *message) bool { return true } +// templateMode represents the mode in which templates are used +// +// It can be +// - empty: templating is disabled +// - a boolean string (yes/1/true/no/0/false): inline-templating mode +// - a filename (e.g. grafana): template mode with a file type templateMode string +// Enabled returns true if templating is enabled func (t templateMode) Enabled() bool { return t != "" } -func (t templateMode) Name() string { - if isBoolValue(string(t)) { - return "" - } - return string(t) +// InlineMode returns true if inline-templating mode is enabled +func (t templateMode) InlineMode() bool { + return t.Enabled() && isBoolValue(string(t)) } +// FileMode returns true if file-templating mode is enabled +func (t templateMode) FileMode() bool { + return t.Enabled() && !isBoolValue(string(t)) +} + +// FileName returns the filename if file-templating mode is enabled, or an empty string otherwise +func (t templateMode) FileName() string { + if t.FileMode() { + return string(t) + } + return "" +} + +// templateFile represents a template file with title and message +// It is used for file-based templates, e.g. grafana, influxdb, etc. +// +// Example YAML: +// +// title: "Alert: {{ .Title }}" +// message: | +// This is a {{ .Type }} alert. +// It can be multiline. type templateFile struct { Title *string `yaml:"title"` Message *string `yaml:"message"`