@@ -255,6 +255,42 @@ func CloseIssue(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, erro
255255 return closeIssue (input , err , connection )
256256}
257257
258+ // CloseIssueByBodyRequest is the body for the body-based close endpoint
259+ type CloseIssueByBodyRequest struct {
260+ IssueKey string `mapstructure:"issueKey" validate:"required,max=255"`
261+ ResolutionDate * time.Time `mapstructure:"resolutionDate"`
262+ OriginalStatus string `mapstructure:"originalStatus"`
263+ }
264+
265+ // CloseIssueByBody
266+ // @Summary close an issue (body-based)
267+ // @Description Close an incident by passing issueKey in the request body.
268+ // @Description Use this when the client (e.g. Kibana) cannot construct a dynamic URL.
269+ // @Tags plugins/webhook
270+ // @Param connectionId path int true "connection ID"
271+ // @Param body body CloseIssueByBodyRequest true "close request"
272+ // @Success 200 {string} noResponse ""
273+ // @Failure 400 {string} errcode.Error "Bad Request"
274+ // @Failure 500 {string} errcode.Error "Internal Error"
275+ // @Router /plugins/webhook/connections/{connectionId}/issue/close [POST]
276+ func CloseIssueByBody (input * plugin.ApiResourceInput ) (* plugin.ApiResourceOutput , errors.Error ) {
277+ connection := & models.WebhookConnection {}
278+ err := connectionHelper .First (connection , input .Params )
279+ if err != nil {
280+ return nil , err
281+ }
282+ request := & CloseIssueByBodyRequest {}
283+ if err2 := helper .DecodeMapStruct (input .Body , request , true ); err2 != nil {
284+ return & plugin.ApiResourceOutput {Body : err2 .Error (), Status : http .StatusBadRequest }, nil
285+ }
286+ vld = validator .New ()
287+ if err2 := errors .Convert (vld .Struct (request )); err2 != nil {
288+ return & plugin.ApiResourceOutput {Body : err2 .Error (), Status : http .StatusBadRequest }, nil
289+ }
290+ input .Params ["issueKey" ] = request .IssueKey
291+ return closeIssue (input , err , connection )
292+ }
293+
258294// CloseIssueByName
259295// @Summary set issue's status to DONE
260296// @Description set issue's status to DONE
@@ -269,6 +305,34 @@ func CloseIssueByName(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput
269305 return closeIssue (input , err , connection )
270306}
271307
308+ // CloseIssueByBodyByName
309+ // @Summary close an issue by connection name (body-based)
310+ // @Description Close an incident using connection name + issueKey in request body.
311+ // @Tags plugins/webhook
312+ // @Param connectionName path string true "connection name"
313+ // @Param body body CloseIssueByBodyRequest true "close request"
314+ // @Success 200 {string} noResponse ""
315+ // @Failure 400 {string} errcode.Error "Bad Request"
316+ // @Failure 500 {string} errcode.Error "Internal Error"
317+ // @Router /plugins/webhook/connections/by-name/{connectionName}/issue/close [POST]
318+ func CloseIssueByBodyByName (input * plugin.ApiResourceInput ) (* plugin.ApiResourceOutput , errors.Error ) {
319+ connection := & models.WebhookConnection {}
320+ err := connectionHelper .FirstByName (connection , input .Params )
321+ if err != nil {
322+ return nil , err
323+ }
324+ request := & CloseIssueByBodyRequest {}
325+ if err2 := helper .DecodeMapStruct (input .Body , request , true ); err2 != nil {
326+ return & plugin.ApiResourceOutput {Body : err2 .Error (), Status : http .StatusBadRequest }, nil
327+ }
328+ vld = validator .New ()
329+ if err2 := errors .Convert (vld .Struct (request )); err2 != nil {
330+ return & plugin.ApiResourceOutput {Body : err2 .Error (), Status : http .StatusBadRequest }, nil
331+ }
332+ input .Params ["issueKey" ] = request .IssueKey
333+ return closeIssue (input , err , connection )
334+ }
335+
272336func closeIssue (input * plugin.ApiResourceInput , err errors.Error , connection * models.WebhookConnection ) (* plugin.ApiResourceOutput , errors.Error ) {
273337 if err != nil {
274338 return nil , err
0 commit comments