@@ -104,14 +104,35 @@ func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error)
104104 path = "issue/" + existingIssue .Key
105105 method = http .MethodPut
106106
107- logger .Debug ("updating existing issue" , "issue_key" , existingIssue .Key )
107+ msg := "updating existing issue"
108+ var disabled []string
109+ if n .conf .Summary .DisableUpdate {
110+ disabled = append (disabled , "summary" )
111+ }
112+ if n .conf .Description .DisableUpdate {
113+ disabled = append (disabled , "description" )
114+ }
115+ if len (disabled ) > 0 {
116+ msg += " without " + strings .Join (disabled , " and " )
117+ }
118+
119+ logger .Debug (msg , "issue_key" , existingIssue .Key )
108120 }
109121
110122 requestBody , err := n .prepareIssueRequestBody (ctx , logger , key .Hash (), tmplTextFunc )
111123 if err != nil {
112124 return false , err
113125 }
114126
127+ if method == http .MethodPut && requestBody .Fields != nil {
128+ if n .conf .Description .DisableUpdate {
129+ requestBody .Fields .Description = nil
130+ }
131+ if n .conf .Summary .DisableUpdate {
132+ requestBody .Fields .Summary = nil
133+ }
134+ }
135+
115136 _ , shouldRetry , err = n .doAPIRequest (ctx , method , path , requestBody )
116137 if err != nil {
117138 return shouldRetry , fmt .Errorf ("failed to %s request to %q: %w" , method , path , err )
@@ -121,10 +142,11 @@ func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error)
121142}
122143
123144func (n * Notifier ) prepareIssueRequestBody (_ context.Context , logger * slog.Logger , groupID string , tmplTextFunc template.TemplateFunc ) (issue , error ) {
124- summary , err := tmplTextFunc (n .conf .Summary )
145+ summary , err := tmplTextFunc (n .conf .Summary . Template )
125146 if err != nil {
126147 return issue {}, fmt .Errorf ("summary template: %w" , err )
127148 }
149+
128150 project , err := tmplTextFunc (n .conf .Project )
129151 if err != nil {
130152 return issue {}, fmt .Errorf ("project template: %w" , err )
@@ -156,12 +178,12 @@ func (n *Notifier) prepareIssueRequestBody(_ context.Context, logger *slog.Logge
156178 requestBody := issue {Fields : & issueFields {
157179 Project : & issueProject {Key : project },
158180 Issuetype : & idNameValue {Name : issueType },
159- Summary : summary ,
181+ Summary : & summary ,
160182 Labels : make ([]string , 0 , len (n .conf .Labels )+ 1 ),
161183 Fields : fieldsWithStringKeys ,
162184 }}
163185
164- issueDescriptionString , err := tmplTextFunc (n .conf .Description )
186+ issueDescriptionString , err := tmplTextFunc (n .conf .Description . Template )
165187 if err != nil {
166188 return issue {}, fmt .Errorf ("description template: %w" , err )
167189 }
@@ -171,14 +193,13 @@ func (n *Notifier) prepareIssueRequestBody(_ context.Context, logger *slog.Logge
171193 logger .Warn ("Truncated description" , "max_runes" , maxDescriptionLenRunes )
172194 }
173195
174- requestBody .Fields .Description = issueDescriptionString
175- if strings .HasSuffix (n .conf .APIURL .Path , "/3" ) {
176- var issueDescription any
177- if err := json .Unmarshal ([]byte (issueDescriptionString ), & issueDescription ); err != nil {
178- return issue {}, fmt .Errorf ("description unmarshaling: %w" , err )
196+ descriptionCopy := issueDescriptionString
197+ if isAPIv3Path (n .conf .APIURL .Path ) {
198+ if ! json .Valid ([]byte (descriptionCopy )) {
199+ return issue {}, fmt .Errorf ("description template: invalid JSON for API v3" )
179200 }
180- requestBody .Fields .Description = issueDescription
181201 }
202+ requestBody .Fields .Description = & descriptionCopy
182203
183204 for i , label := range n .conf .Labels {
184205 label , err = tmplTextFunc (label )
@@ -395,3 +416,7 @@ func (n *Notifier) doAPIRequestFullPath(ctx context.Context, method, path string
395416
396417 return responseBody , false , nil
397418}
419+
420+ func isAPIv3Path (path string ) bool {
421+ return strings .HasSuffix (strings .TrimRight (path , "/" ), "/3" )
422+ }
0 commit comments